View Full Version : Using Virtualdub or AVISynth filter from external program
timecop
5th March 2003, 10:54
I am writing a utility for my personal use and I would like to use a VirtualDub (or Avisynth, the plugin in question can be used from both), inside it.
Ideally, I would want to copy just enough of plugin loading glue from VirtualDub/Avisynth to handle loading a single plugin, show its config dialog, and then be able to execute it for each frame of 24bit rgb data as returned by AVIStreamGetFrame()
Yes, I could take the plugin's source code and adapt it to be used with my program, but I would rather load it dynamically because of future bugfixes in the plugin, and to avoid having to duplicate code already written and working fine elsewhere.
Is there a tutorial or documentation somewhere on vdub / avisynth internals related to plugin loading? I looked at the source code of both, there is no documentation or comments whatsoever, so its rather difficult to figure out at this moment.
Any ideas would be appreciated, also if someone written similar code before (some other application capable of loading vdub plugins), post some links so I can borrow their code :)
sincerely yours,
timecop
Belgabor
5th March 2003, 11:54
Heya tc :)
If you don't mind being dependant on AviSynth I would recommend using it, not via loading of an avs, but dynamically. You can find some code on how to do that in the CVS of ffdshow, here (http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/ffdshow/ffdshow/src/imgFilters/avisynth/TimgFilterAvisynth.cpp) to be specific (click on 'view' of the latest version if you're not familiar with ViewCVS). If yuo don't want that I can't help you, I'm not familiar with that part of the VDub source, sorry.
Cheers
Belgabor
timecop
5th March 2003, 13:26
Originally posted by Belgabor
Heya tc :)
If you don't mind being dependant on AviSynth I would recommend using it, not via loading of an avs, but dynamically. You can find some code on how to do that in the CVS of ffdshow, here (http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/ffdshow/ffdshow/src/imgFilters/avisynth/TimgFilterAvisynth.cpp) to be specific (click on 'view' of the latest version if you're not familiar with ViewCVS). If yuo don't want that I can't help you, I'm not familiar with that part of the VDub source, sorry.
Cheers
Belgabor
This is exactly why I was trying to find you on IRC today :D
Hm. It seems like the code snippet there simply dynamically creates a avisynth script and loads it. I was trying to avoid that so that I could process arbitrarily bits of data, as opposed to working in the "video" context. While this application is somewhat video related, it does not necessarily need to process .avi files.
I was looking for the capability of running the filter *just* to process a chunk of image. Hmm.
Belgabor
5th March 2003, 15:24
Look carefully at it, yes it creates a script, but it uses an internal source function to provide the video data, it doesnt need a file (avi or whatever), you can give this function whatever video data you want. You're right, its 'videoish', but nothing keeps you from creating a 'video' with only one frame.
The only diffrence/problem with this aproach is, in contrast to some other filtering you might think of, is, you pull data through it, not push it, but thats not much of a diffrence if you only use one frame ;)
timecop
6th March 2003, 06:29
Originally posted by Belgabor
Look carefully at it, yes it creates a script, but it uses an internal source function to provide the video data, it doesnt need a file (avi or whatever), you can give this function whatever video data you want. You're right, its 'videoish', but nothing keeps you from creating a 'video' with only one frame.
The only diffrence/problem with this aproach is, in contrast to some other filtering you might think of, is, you pull data through it, not push it, but thats not much of a diffrence if you only use one frame ;)
After spending almost entire day trying to figure this out I still dont get it.
AVSValue eval_args[] = { script, "script_processor" };
AVSValue val = env->Invoke("Eval", AVSValue(eval_args, 2));
if (val.IsClip()) {
clip = new PClip;
*clip = val.AsClip();
framenum = 0;
} else {
OutputDebugString(L"Eval result is not a clip\n");
return false;
}
Isn't that supposed to execute some FUNCTION inside my AVS?
What should my "source" avs look like?
strcpy(script,
"LoadPlugin(\"c:\\dvd\\avisynth\\plugins\\leetplug.dll\")\n"
"Function script_processor() {\n"
" leet_source()\n" /* my source function, below */
" return LeetPlug(params)\n"
"}\n"
);
When this is run, avisynth doesn't return a clip.
ffdshow source is horrible, horrid indenting, and absolutely not commented. Typical opensores software, I guess.
Anyhow, I am still not able to get it to work.
My guesses after studying that code are:
* I need to implement leet_source() class and leet_source::GetFrame()
which prepare a video frame returned by AVIStreamGetFrame(). This is the piece of data to be processed.
* I need to prepare script environment and load the dummy avs into it
* write Process function which:
a) PVideoFrame frame = (*clip)->GetFrame(n, env); // gets the processed frame
b) memcpy(data, frame->GetReadPtr(), params); // copies the processed data back into my image buffer
Anyhow, this doesn't work.
I get back data, but any of my actual scripting seems to be ignored.
I get the identical image back that I feed to leet_source::GetFrame()
Unless I am missing something?
Belgabor
6th March 2003, 13:45
Originally posted by timecop
AVSValue eval_args[] = { script, "script_processor" };
AVSValue val = env->Invoke("Eval", AVSValue(eval_args, 2));
I don't know what the second argument is for, but I think you misunderstood. So your script should go like this (I think):
strcpy(script,
"LoadPlugin(\"c:\\dvd\\avisynth\\plugins\\leetplug.dll\")\n"
"leet_source()\n" /* my source function, below */
"LeetPlug(params)\n"
);
* I need to implement leet_source() class and leet_source::GetFrame()
which prepare a video frame returned by AVIStreamGetFrame(). This is the piece of data to be processed.
* I need to prepare script environment and load the dummy avs into it
* write Process function which:
a) PVideoFrame frame = (*clip)->GetFrame(n, env); // gets the processed frame
b) memcpy(data, frame->GetReadPtr(), params); // copies the processed data back into my image buffer
Yes, this should be it. But if it doesnt work with the modified script, I don't know what could be wrong anymore :(
timecop
6th March 2003, 16:27
Finally figured it out.
The filter I am interested in only worked in YUV. leet_source() was (obviously) returning RGB24.
I tried with AVISynth's Subtitle("blah") and immediately saw yellow "blah" in upper left :D
Adding ConvertToYUY2() before calling LeedPlugin() works, but is just a temporary hack so I can spend the next 8 hours sleeping and dreaming that I wasted last 2 days on this just because of different colorspaces. Then tomorrow I'll see how to make AVIFile give me YUY output for AVIStreamGetFrame() and then I can work without having to convert to YUY2 and back (its *damn* slow now with those 2 conversions).
Hm, I guess case closed. Using avisynth from within another application is damn easy :D
Belgabor
7th March 2003, 13:12
Good to hear =) Now I know whom I have to poke if I can't get it to work in my case ;)
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.