¶VirtualDub 1.6.7 released
I had intended for 1.6.6 to be the first stable release in the 1.6.x series, but a couple of bugs were reported that required potentially risky changes, so I decided to push 1.6.7 out as experimental again and reset the clock. Again, barring no major issues, the next release — 1.6.8 — will be released as stable.
1.6.7 mostly contains a bunch of minor crash fixes, but has two notable changes. One is that the AVI indices have been moved inward a couple of chunks to match the OpenDML spec; they were formerly placed at the very end, outside of any other chunk. The only reason this got noticed is that someone was comparing VirtualDub's output to their own AVI writer; I doubt anyone will notice a difference otherwise, but if there is a problem with the old index placement, it can be rectified by re-running the AVI through VirtualDub in direct/direct mode. The other notable change is that I fixed a couple of issues with audio samples being dropped at the very end of the output file.
In the other branch....
I'm still working on the 1.7.0 branch, albeit slowly. One of the fixes in 1.6.7, the lowpass crash, I actually discovered by accident while merging the audio filter system's scheduler into the main scheduler in 1.7.0. Doing this wouldn't have been too bad except that the way I pulled audio out of the filter graph wasn't multithread-savvy in that it couldn't re-wake the sleeping graph, so I had to add additional rescheduling calls. After the audio filter work is complete I want to get the video filter system running multithreaded. In theory this will Just Work(tm) for most filters, since the scheduler guarantees that execution within a particular filter instance is always serialized. A few third-party ones, though, do naughty things with VirtualDub's internal structures or otherwise are non-reentrant, and would need to be serialized.
Re-threading the system is tricky work, and much harder to do while rewriting an existing system than when writing a new one from scratch. One of my pet peeves with regard to multithreaded code is seeing code like this:
while(condition_hasnt_occurred) { Sleep(10); }
A Sleep() loop is not a proper synchronization mechanism and fares badly as one, both in latency and scalability. It also doesn't work in a user-space scheduling system like mine where tasks can't sleep in-place, since they have to return back to the scheduler to suspend. Unfortunately, I can't use regular synchronization primitives either since they can't be used in a partially cooperatively-tasked system, so I have to manually have signallers reschedule the waiters instead. One nice side effect of having to do this, though, is that all waits occur in the scheduler, meaning that I no longer have to worry about providing an abort path for every wait — I can simply set the abort flag in the scheduler and have all processing threads exit from there.
Changelist
Build 23538 (1.6.7, experimental): [June 12, 2005]
[features added]
* Script: Added support for cast expressions to int/long/double.
* Video direct-stream path now treats zero-byte (drop) frames as non-
essential. A video stream that has been spaced with drop frames to a
higher frame rate can now be cleanly converted down as well.
[bugs fixed]
* Fixed crash when decoding audio from broken or mismatched DV frame.
* Hierarchical AVI index blocks were being placed outside of RIFF chunks.
No known actual incompatibility cases (yet).
* Fixed occasional crash when using lowpass or highpass filters with a
large tap count.
* Fixed crash on attempting to abort a render when an error had already
occurred.
* Fixed "cut off audio stream when video stream ends" sometimes being
active even after being disabled.
* Fixed audio stream being shortened slightly when using audio compression.
* Capture: Fixed crash in volume meter code triggered by load of DLLs that
whack the floating-point control word.
* Capture: Fixed crash on exit in DirectShow layer caused by shutting down
COM too early.
[regressions fixed]
* Script: Fixed "method not found" errors loading .vcfs caused by failure
to convert longs to ints.