Tutorial step 4: adding start and end routines |
||
|
Let's say we want to change our processing formula, so that instead of dividing green and blue in half, we divide it by 3 instead. This immediately gets gross. Division is veeeeeeerry slow, and multiplication tricks aren't much faster and lead to all sorts of rounding problems. Instead, we'll use lookup tables. Now, the only question is where to allocate and initialize the tables. The startProc and endProc functionsThe startProc function is called immediately before processing starts, and endProc after processing ends. These are the ideal routines to allocate and initialize whatever extra work buffers, lookup tables, or dynamic code strings that may be needed. These functions have the usual prototypes:
Function startProc(fa: PFilterActivation; const ff: PFilterFunctions): Integer; cdecl; As usual, return zero for success, non-zero for failure. Unlike the module init functions, VirtualDub calls the endProc function for all filters in the processing chain, including those that have not been initialized and the filter that failed. This means you must keep track of elements that were never allocated (*cou NULL gh*), but also means that you need not worry about deallocating anything in startProc on failure; you can simply net stopProc clean up the partial allocations. For this to work, though, you must have instance data for the filter. This is done with a non-zero inst_data_size field in the FilterDefinition structure. VirtualDub will automatically allocate a memory block of that size and point the fa->filter_data member to it when a filter instance is created, and deallocate it when instances are destroyed. The memory block is also cleared with zeroes on creation. Because VirtualDub automatically handles instance data allocation, if your filter specifies it needs an instance data block the fa->filter_data pointer will always be valid whenever one of the filter functions is called.
Modifying the tutorial filter to use lookup tablesFirst step is to create a structure for our instance data. We'll use two 1K lookup tables, one for green and one for blue. With a Pixel32 for each entry, we can save ourselves some post-shifting trouble.
type Next, update the FilterDefinition record:
Const Now, write the startProc and stopProc routines. These need not be particularly fast, so there's no sense in optimizing them much:
Function tutorialStartProc(fa: PFilterActivation; const ff: PFilterFunctions): Integer; cdecl; Finally, rewrite the runProc routine to use lookup tables:
Function tutorialRunProc(const fa: PFilterActivation; const ff: PFilterFunctions): Integer; cdecl; The operation was completed successfully. Your project file should now look like this. Compile and test it. |
||
© 2005 Fernando Reis < >Adapted from VirtualDub external filter SDK 1.05 documentation © 1999-2001 Avery Lee |