PDA

View Full Version : Returning Invoke(d) frame


Si
26th October 2003, 21:00
Dear Experts :)
I am trying to use env->Invoke to double the width of the source video.

I can manipulate the invoked clip and even copy resized pixels from the invoked frame back to a normal dst frame.

But I can't seem to return the invoked frame - I get an Avisynth access violation error when previewing in VirtualDubMod :(

Am I trying something illegal or is it my coding?

(Has anyone already done something like this and could they point me to it ?)

regards
Simon

sh0dan
27th October 2003, 10:02
... you cannot return frames with different sizes from the same filter, if that's what you're trying to do.

The size of your returned PVideoFrame MUST be the size you specify in "Videoinfo vi", when you return your filter after it has been created.

If you cannot be sure, you must check the size/colorspace yourself.

Si
27th October 2003, 13:58
I'm not trying to return varying width - I'd like to always return double the width of the source.

Can I change vi.width somewhere (constructor/ GetFrame ???) or is it impossible in a plugin?

regards

Simon

Bidoche
27th October 2003, 14:25
One should adjust videoinfo in filter constructor, with vi.width = ... in your case.

Si
27th October 2003, 15:04
Thanks - I don't even need Invoke at all (but it now works anyway :) ).

I didn't realise it was that simple :o

regards
Simon

WarpEnterprises
28th October 2003, 22:48
Now you made me nosy (is this correct english?) : what was your simple solution?

Si
29th October 2003, 12:54
public:
ShowPixelValues(PClip _child,
bool _ShowValues, int _Left, int _Top, bool _ShowArea, int _param5,
IScriptEnvironment* env) :
GenericVideoFilter(_child),
ShowValues(_ShowValues), Left(_Left),
Top(_Top), ShowArea(_ShowArea), param5(_param5)

{
// constructor code
if (vi.IsPlanar())
env->ThrowError("ShowPixelValues: input to filter must be in YUY2 or RGB32 colorspace");

vi.width = vi.width*2;
}
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
};

PVideoFrame __stdcall ShowPixelValues::GetFrame(int n, IScriptEnvironment* env) {


PVideoFrame src = child->GetFrame(n, env);
PVideoFrame dst = env->NewVideoFrame(vi);
...

With this code, you end up with the dst frame having double the width of the src frame :D

regards
Simon

sh0dan
29th October 2003, 13:41
I've spotted a bug:
if (vi.IsPlanar())
env->ThrowError("ShowPixelValues: input to filter must be in YUY2 or RGB32 colorspace"); YV12 must be supported for this to be a valid filter! :sly:

OK - seriously - you should just do: if (!(vi.IsRGB32()||vi.IsYUY2()))
env->ThrowError("ShowPixelValues: input to filter must be in YUY2 or RGB32 colorspace");

Si
29th October 2003, 14:48
Ta

Simon

WarpEnterprises
29th October 2003, 20:15
hey, but the new frame is EMPTY. And I thought you can save the resizer.
Am I right?

Si
29th October 2003, 20:26
I was only using Invoke to try to get a double sized frame - I didn't actually want to resize the input.

I'm writing a filter to examine pixels values - putting magnified ones on the left and original frame on the right.

I haven't fully explored how to use Invoke but if you add the following code
class ShowPixelValues : public GenericVideoFilter {
bool ShowValues, ShowArea;
int Left, Top, param4, param5;
PClip resized;



public:
ShowPixelValues(PClip _child,
bool _ShowValues, int _Left, int _Top, bool _ShowArea, int _param5,
IScriptEnvironment* env) :
GenericVideoFilter(_child),
ShowValues(_ShowValues), Left(_Left),
Top(_Top), ShowArea(_ShowArea), param5(_param5)

{
// constructor code
if (!(vi.IsRGB32()||vi.IsYUY2()))
env->ThrowError("ShowPixelValues: input to filter must be in YUY2 or RGB32 colorspace");// resized = new PClip;


AVSValue args[3] = { child, (vi.width*2), (vi.height) };

resized = env->Invoke("BilinearResize",AVSValue(args,3)).AsClip();
vi.width = vi.width*2;


}

PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env);
};



PVideoFrame __stdcall ShowPixelValues::GetFrame(int n, IScriptEnvironment* env) {


PVideoFrame src = child->GetFrame(n, env);
PVideoFrame dst = env->NewVideoFrame(vi);
// PVideoFrame test = resized->GetFrame(n,env);
...
then you can copy the pixels from test to dst - I'm sure it's not the fastest way to do it but it works :)

regards
Simon

WarpEnterprises
29th October 2003, 21:34
Nice.
Why shouldn't it be fast? The resizer is constructed only once, and sh0dan (?) mentioned that only Invoking in GetFrame is slow, as the resizer would be constructed for each frame.

Si
30th October 2003, 00:50
Because I write the slowest code ever :p

regards
Simon

morsa
16th February 2004, 00:44
I think this way of changing the destination frame size should be added to the filter SDK page IMO.

Si
16th February 2004, 07:20
Done :)

regards
Simon

sh0dan
17th February 2004, 09:52
Originally posted by siwalters
[...]then you can copy the pixels from test to dst - I'm sure it's not the fastest way to do it but it works :)

regards
Simon
Actually you can just return "test", which might be a tad faster.