PDA

View Full Version : Issues using avisynth through libary interface


kemuri-_9
12th October 2009, 01:58
I've been trying to extend x264 to be able to open .avs files through avisynth.dll directly
rather than let windows do it through the VFW interface,
but I've been having an issue with it I've not been able to fix.

the code fragment surrounding the issue is

typedef struct {
PClip clip;
IScriptEnvironment *env;
HMODULE lib;
} avs_input_t;

int open_file_avs( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param )
{
avs_input_t *h = (avs_input_t*)malloc( sizeof(avs_input_t) );
int i_frames;
if( !h )
return -1;
try
{
h->lib = LoadLibrary( "avisynth" );
if( !h->lib )
{
fprintf( stderr, "avs [error]: failed to load avisynth" );
return -1;
}
IScriptEnvironment* (* CreateScriptEnvironment)( int version ) =
(IScriptEnvironment*(*)(int)) GetProcAddress( h->lib, "CreateScriptEnvironment" );
if( !CreateScriptEnvironment )
{
fprintf( stderr, "avs [error]: failed to load CreateScriptEnvironment()\n" );
return -1;
}
h->env = CreateScriptEnvironment( AVISYNTH_INTERFACE_VERSION );
if( !h->env )
{
fprintf( stderr, "avs [error]: failed to initiate CreateScriptEnvironment()\n" );
return -1;
}
AVSValue arg( psz_filename );
AVSValue res = h->env->Invoke( "Import", arg );
...
}


the issue is that
h->env = CreateScriptEnvironment( AVISYNTH_INTERFACE_VERSION );
is corrupting the EAX register, so a seg fault occurs shortly thereafter.

I'm exporting this and some other related functions as C, since x264 is currently completely only in C
I chose to use the C++ interface and export the function as C because the C interface does not seem be well maintained...

Is the EAX register corrupting a known issue for this kind of situation?
Or am I just going to have to bite the bullet and use the C interface?

IanB
12th October 2009, 08:49
I do not understand "corrupting the EAX register", the eax register is how C/C++ functions return 32 bit values. I would expect eax to contain either 0 (failure) or a pointer to the IScriptEnvironment object.

What compiler are you using? Only the M$ compiler works. To use GCC you will have to fight with the C interface.

For further down the track you should wrap try/catch around everything. CreateScriptEnvironment can throw any errors from loading all the .AVSI's and .DLL's you may have in your plugin directory. Other calls throw as appropriate for the context. Typical things to explicitly catch are classes IScriptEnvironment::NotFound and AvisynthError. Be careful processing AvisynthError::msg it can be corrupted by dodgy plugins and point to invalid addresses.

kemuri-_9
12th October 2009, 10:28
i was meaning "corrupting the EAX register" literally, as it becomes irregular and a seg fault occurs on the next assembly instruction that reads from it.

I was originally trying this with both g++ and msvc:
msvc reported that the eax register became corrupted with its runtime checks,
and g++ proceeded to seg fault at the Invoke command or there about.

the entire code was wrapped in a
try { ... } catch( AvisynthError err ) { ... }

but it never got caught in this situation,
not even
catch( ... ) { ... } did any good.

I just think this is an incredibly weird side effect of trying to use the C++ interface, but then exporting it to use with a C program.

either way, i've rewritten everything using the C interface already, so am no longer having any problems with this...

Malaksbane
12th October 2009, 10:41
try-catch reacts on a throw in the called function, it will not automagically detect errors.

Did you check that the function pointer returned from GetProcAdress is valid, or just probably valid?

kemuri-_9
13th October 2009, 01:00
i have already switched over to using the C interface now and deleted all the code i had which used the C++ interface.

i only remember confirming that avisynth was loading at address 0x10000000.
i don't remember what the address of CreateScriptEnvironment was...

I guess this can be a heads up for others to avoid what i was originally trying :rolleyes: