Features new to VirtualDub 1.4

VirtualDub 1.4 contains a couple incremental changes to the filter SDK you might be interested in.  If you want to use these extensions, but don't want to break compatibility with VirtualDub 1.2, you can do so by checking the vdfd_ver flag passed to your DLL's initialization function.  This value is 4 for V1.2, 5 for V1.3d, and 6 for V1.4.  By default, the sample init function given in the tutorial allows your filter to run under V1.2, so you will want to explicitly hardcode 6 in the return value if you need to use V1.4 functionality.

Exception handling

The recommended course of action for VirtualDub 1.3 filters when failing a filter init or start is to return a non-zero value.  Obviously, this is not very descriptive and leads to user confusion when a filter fails.  Starting with VirtualDub 1.4, there are two new functions in the SDK in the FilterFunctions structure:

void (*ExceptOutOfMemory)();
void (*Except)(const char *format, ...);

The first is simple: you call it when you run out of memory.  The second allows you to throw any descriptive error string, although keep it short please (<128 bytes is good).  Both functions will abort your code by throwing a C++ exception back, so unless your code is simple enough to not require any exception handling, it is recommended that you either wrap code in try { } catch(...) { } handlers to clean up along the way, or implement your own exception handling and throw VirtualDub's exception at the end of the filter function.

You can only use these functions from within initProc, startProc, and runProc.  Throwing exceptions anywhere else will cause crashes.

CPU detection

VirtualDub 1.4 has vastly better CPU detection over previous versions.  The third new function in FilterFunctions is getCPUFlags().  This function returns a bitfield which states all the CPU extensions you are allowed to use:

Reusing the stack pointer

In the Win32 environment, it is possible to change ESP away from the stack, because interrupts do not occur on the user-mode stack.  Although it is still recommended that you bump ESP down before accessing stack automatics, ESP can used to point to other data.  VirtualDub 1.4 provides a way to do this while still allowing reentrancy; it is possible to code a routine that reuses ESP while being run concurrently on different threads.  To do this, the entire routine should be written in assembly language.

When VirtualDub starts a thread, it initializes the application dword at fs:[14h] to a thread-specific data structure.  The first 68 bytes of this structure are reserved for functions that wish to reuse ESP, with the top four bytes used for ESP itself.  That means, to reuse ESP, you should code as follows:

mov     eax,dword ptr fs:[14h]

;[move stack values into thread-specific space]

mov     dword ptr [eax+40h],esp
mov     esp,new_value

...

mov     eax,dword ptr fs:[14h]
mov     esp,dword ptr [eax+40h]

All values in the first 64 bytes pointed to by fs:[14h] should be considered forfeit as soon as you jump away from the current function in any way; this includes calling VirtualDub functions or returning from filter functions.  You should not store non-constant values for your inner loop in global variables, as this will make your routine non-reentrant.  If you need to use absolute addressing, copy the code block to a new memory area and relocate the addresses to new locations.  Also, do not call any VirtualDub functions with ESP set away from the normal stack -- you may derail exception handling if you do so.  Finally, never modify fs:[14h] under any circumstances.

Be aware that debugging a routine that modifies ESP may inhibit your ability to debug the routine.  You should attempt to optimize the routine with a regular stack pointer before freeing up ESP for an 8th register.

[up] back to main page


VirtualDub external filter SDK 1.03©1999-2000 Avery Lee (uleea05@umail.ucsb.edu)