Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Reply
 
Thread Tools Search this Thread Display Modes
Old 31st July 2018, 22:30   #1  |  Link
videoh
Useful n00b
 
Join Date: Jul 2014
Posts: 1,407
How to let a filter change the video format?

I have a filter that accepts and returns YUV420P16 and works correctly. I want to have it optionally return YUV420P8. I'd appreciate guidance.

Last edited by videoh; 1st August 2018 at 20:08.
videoh is offline   Reply With Quote
Old 31st July 2018, 23:18   #2  |  Link
TheFluff
Excessively jovial fellow
 
Join Date: Jun 2004
Location: rude
Posts: 1,095
Normally the way you do this is on filter instantiation:

1. Create a new VSFormat struct to use for your output using vsapi->getFormatPreset (or if you're doing something exotic, using vsapi->registerFormat)
2. Call vsapi->setVideoInfo on your output node with the new format.

If you want to be able to dynamically change output format at the time when getFrame is called then I dunno if this will work.
TheFluff is offline   Reply With Quote
Old 1st August 2018, 02:54   #3  |  Link
videoh
Useful n00b
 
Join Date: Jul 2014
Posts: 1,407
I'll give that a try.

What is my "output node"? I have a node passed to me by
static void VS_CC dghdrtosdrInit(VSMap *in, VSMap *out, void **instanceData, VSNode *node, VSCore *core, const VSAPI *vsapi)
Is that an input node or an output node? If the former, where does the output node come from?

Thank you.

Last edited by videoh; 1st August 2018 at 02:57.
videoh is offline   Reply With Quote
Old 1st August 2018, 03:07   #4  |  Link
TheFluff
Excessively jovial fellow
 
Join Date: Jun 2004
Location: rude
Posts: 1,095
Sorry, I was confusing myself there. Yes, that's the output node. In Avisynth parlance, it's the clip your filter returns (well, close enough to it anyway).

e: if you're intending to create a clip where the pixel format changes between frames, you need to set node->VI->format to NULL (using vsapi->setVideoInfo) on filter instantiation to tell VS that this clip doesn't have a constant pixel format (see struct VSFormat in the docs), but I'm not sure how you change the format on a per-frame basis after that. I've never tried to do that.

Last edited by TheFluff; 1st August 2018 at 03:13.
TheFluff is offline   Reply With Quote
Old 1st August 2018, 03:40   #5  |  Link
videoh
Useful n00b
 
Join Date: Jul 2014
Posts: 1,407
I need to do it only at instantiation. I'll try using the node passed in to the init function as you suggested.

Last edited by videoh; 1st August 2018 at 20:08.
videoh is offline   Reply With Quote
Old 1st August 2018, 08:01   #6  |  Link
HolyWu
Registered User
 
HolyWu's Avatar
 
Join Date: Aug 2006
Location: Taiwan
Posts: 755
I think that you shouldn't bother to output a clip of different bit depth than the input. Most (if not all) VS filters just keep the same bit depth. The users may have their own preference of dithering method when they need to reduce the bit depth.

Anyway, https://gist.github.com/HolyWu/f75d0...5e56065fcae459 is a modified example of Invert filter to demonstrate what you want.
HolyWu is offline   Reply With Quote
Old 1st August 2018, 08:02   #7  |  Link
Mystery Keeper
Beyond Kawaii
 
Mystery Keeper's Avatar
 
Join Date: Feb 2008
Location: Russia
Posts: 717
Quote:
Originally Posted by videoh View Post
Looking more closely I don't think that can be correct. The init function already has:

VSVideoFilter *vs = (VSVideoFilter *)*instanceData;
vsapi->setVideoInfo(vs->VI, 1, node);

That VI was obtained from this code in the create function:

VSNodeRef *node = vsapi->propGetNode(in, "clip", 0, 0);
const VSVideoInfo *VI = vsapi->getVideoInfo(node);

So the node passed to the init function appears to be the input node. How do I get the output node (VSNode)?

propGetNode returns a VSNodeRef while the setVideoInfo function takes a VSNode, so I can't use propGetNode to get the output VSNode. The documentation is unclear about the difference between VSNode and VSNodeRef and leaves me completely confused.
No. The node in the Init function is your filter node.
In Create function you save whatever info you need in the instance data structure.
A pointer to that structure is passed in all other callbacks.
In the example the VideoInfo from the input node is copied and set for the output node.
You can change it to your liking.
Don't forget that VSFormat is not to be created manually, but registered or retrieved with getFormatPreset();
__________________
...desu!
Mystery Keeper is offline   Reply With Quote
Old 1st August 2018, 14:32   #8  |  Link
videoh
Useful n00b
 
Join Date: Jul 2014
Posts: 1,407
@HolyWu, I just now noticed your reply slipped in between my post and Mystery Keeper's reply. I will give it a try. Thank you very much for taking the time to put that together.

The internal conversion to 8-bit is for those looking for maximum performance. If they want to do things like dithering externally, they can just output fulldepth.

Last edited by videoh; 1st August 2018 at 20:09.
videoh is offline   Reply With Quote
Old 1st August 2018, 15:01   #9  |  Link
videoh
Useful n00b
 
Join Date: Jul 2014
Posts: 1,407
@HolyWu

Works great. Thanks a million!
videoh is offline   Reply With Quote
Old 1st August 2018, 15:50   #10  |  Link
jackoneill
unsigned int
 
jackoneill's Avatar
 
Join Date: Oct 2012
Location: 🇪🇺
Posts: 740
Code:
typedef struct VSVideoInfo {
    const VSFormat *format;
    ...
Code:
VSFormat *fi = (VSFormat *) vs->VI->format;
Reminds me of people who see the red light but cross the street anyway...
__________________
Buy me a "coffee" and/or hire me to write code!
jackoneill is offline   Reply With Quote
Old 1st August 2018, 19:26   #11  |  Link
Mystery Keeper
Beyond Kawaii
 
Mystery Keeper's Avatar
 
Join Date: Feb 2008
Location: Russia
Posts: 717
Quote:
Originally Posted by jackoneill View Post
Code:
typedef struct VSVideoInfo {
    const VSFormat *format;
    ...
Code:
VSFormat *fi = (VSFormat *) vs->VI->format;
Reminds me of people who see the red light but cross the street anyway...
More likely a case of inexperience than recklessness. But yes, not good.
__________________
...desu!
Mystery Keeper is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 01:05.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.