[icon] VirtualDub - [archive news]
  Home   Download   WIP   Features   Screenshots   Documentation   FAQ   Knowledge Base   News   Links   License   Contact  
The latest version of VirtualDub is 1.4c (11759).

This is an archive of old news.  You should be reading current news instead.

 12/02/2001: How seeking in AVI really works, a.k.a. why your sync is off

How many AVI parsers do you think Microsoft ships with Windows?  One?  Two?

Three, actually.  The MCIAVI driver, AVIFile, and DirectShow's AVI splitter.  And it turns out that all act slightly different.

I finally started attacking that sync problem that people have been reporting with VirtualDub for ages, and after several hours of reverse engineering, it turns out that it's actually caused by Nandub.  Now, I've warned Nando repeatedly about the way in which vdub-mp3, and later Nandub, sets certain fields in the audio stream header when it uses an MP3 file as input.  To put it bluntly, they're invalid.  And it turns out that they sometimes work, and sometimes they don't.  On the same file.  It only happens if you use an MP3 file as input -- VBR or not -- and doesn't happen if you actually compress to MP3 in Nandub itself.

The way Nandub tries to set up (VBR) MP3 streams is as follows:

  • dwSampleSize = 0 (VBR samples)
  • dwRate/dwScale = sampling_rate/1152 (rate of compressed samples)
  • nBlockAlign = 1152 (block size)

dwSampleSize, as it turns out, is totally ignored by both the AVIFile and DirectShow AVI parsers for audio streams, so setting it to zero for VBR operation doesn't work at all -- the AVI parsers use the nBlockAlign value of 1152 regardless.  The significance of the dwRate/dwScale fraction is that MPEG-1 audio frames decompress to 1152 samples each; it turns out that this is incorrect for MPEG-2 (16-24KHz) and MPEG-2.5 (8-12KHz) streams, but those are usually low bitrate and seldom used.  Now, you'll notice that dwRate/dwScale is independent of bitrate here, so with a fixed blocksize and a compressed sample rate regardless of bitrate, the audio stream should be horribly desynchronized.

Except for the strange nBlockAlign value and the way that Nandub writes out audio samples.

Nandub writes each MPEG audio frame as a separate chunk in the file.  Ordinarily, this is a bad idea because it causes multiple audio blocks to be written for each video frames and consumes a couple of additional % in the AVI for headers.  The odd thing here is that this causes all of the audio chunks to be smaller than the nBlockAlign value.  This ends up interacting with an interesting bug/feature in the DirectShow AVI parser, which, for seeking purposes, rounds up all of the chunk sizes.  Since no MPEG frame created by the MP3 codec is 1152 bytes or larger, this causes DirectShow to seek as if every MPEG frame was a sample, which gives accurate seeking even with VBR streams.  In actuality, any nBlockAlign value will work as long as it is as least as large as the biggest audio chunk in the file.

So everything is hunky dory and we can use VBR audio, right?  Unfortunately, not really.

First, DirectShow's buffering does not seem to react very quickly to VBR audio, and if you have high variance in the audio stream, it can cause the video playback to suddenly speed up or slow down.  Second, neither DirectShow nor AVIFile will write out an audio stream in this way, so nearly any other program will trash the AVI file when it's rewritten.  DirectShow actually refuses to rewrite the stream with an "The data is invalid" error if you try using GraphEdit in a direct copy configuration (File reader -> AVI splitter -> AVI mux -> File writer), even though it works if you disconnect the audio stream or decompress it, or use a regular AVI file.

The killer, though, is that AVIFile's parser rounds down instead of up when it sees blocks that aren't a multiple of nBlockAlign.  Thus, AVIFile sees zero samples where DirectShow sees one, and as a result AVIFile-based programs cannot read any audio samples at all from a Nandub MP3-based AVI file.  Because AVIFile reports the dwLength header value when AVIStreamLength() is called, this generally results in some nice errors when AVIFile-based applications attempt to read the files and can't get any samples at all.  The eventual point of all of this is that the AVI files are basically trashed.  No offense to Nando, since it's a pretty neat trick, but the truth is that it just doesn't work for anything other than playing in Windows Media Player.  (This also applies to the many DirectShow-based players out there, like Sasami2k, which are basically the same DirectShow engine with some add-ons.)  The files are useless for editing.  Tsunami MPEG Encoder 2.0's OpenDML parser doesn't like the files either and either reads no audio or badly broken audio when faced with odd-size chunks.  You can get Tsunami to work, however, if you force it to use DirectShow to read the source AVI.

MCIAVI, as it turns out, seems to read almost anything correctly, and will even play Nandub MP3-compressed files even when nBlockAlign is lowered below the MPEG frame size, which neither AVIFile nor DirectShow will handle -- quite a testament to the original Video for Windows programmers.  However, I seriously doubt that many of you will want to switch to mplay32.exe and Video for Windows to play your movies.

So what happened with VirtualDub?

V1.4c actually handled Nandub MP3 files ok, because it supported VBR operation for dwSampleSize=0.  I changed this behavior in V1.4d when I discovered the Microsoft behavior, in order to fix the crash with Canopus AVI files.  That turned out to cause the problem with VirtualDub destroying the audio sync on Nandub files, because it then acted similar to the way that AVIFile does.  I am going to have to come up with a workaround for V1.4.8, but the truth of the matter is that there is still no reliable way to stick VBR audio in AVI files.  Doh!

If anyone has comments or corrections to the above, I've love to hear them.

As a side note, someone finally explained how people are getting the Windows 98 version of the Asus ASV1 codec installed on Windows XP: apparently, it happens if you upgrade a 98/ME system with an Asus capture-capable video card to XP.  Whoops.  If you haven't figured it out yet, installing an upgrade of Windows over an older version is generally a bad idea, and you should always do a full install.

 10/27/2001: Why the ASUS ASV1 codec crashes VirtualDub under Windows 2000

I finally figured out why some of you have been saying that VirtualDub isn't compatible with Windows 2000 and XP, when it is.

I've been getting bug reports that VirtualDub crashes when you attempt to select a video codec, which all happen to include these very relevant sections:

7f84171c: xor	eax,eax
7f84171e: mov	dl,41
7f841720: mov	ecx,53555341
7f841725: cmp	[eax+0c0000h],dl      <-- FAULT
7f84172b: jnz	7f841735
7f84172d: cmp	[eax+0c0000h],ecx
7f841733: jz	7f84173d
7f841735: inc	eax
7f841736: cmp	eax,00000100
7f84173b: jl	7f841725
7f84173d: cmp	eax,00000100
7f841742: jl	7f841756

Windows 5.0 (Win2000 build 2195) [Service Pack 2]

7f841725: asusasv1!DriverProc(0, 0) [7f840000+1000+725]

The ASUSASV1.DLL driver is designed to run only under Windows 95/98.  When VirtualDub calls ICOpen() to open the ASUS driver, the driver attempts to scan a block of memory from 000C0000 to 000C00FF for the string "ASUS."  One of the "features" of Windows 95/98 is that all Win32 processes have the DOS memory arena from 10000-FFFFF mapped verbatim into their memory space for read/write access, a major security and stability hole of those operating systems.  It happens that the video BIOS for most cards resides from C0000-C7FFF, and the above code tries to make sure that you own an ASUS video card.  All of the Windows NT platforms (NT, 2000, XP) have real memory protection and don't let you do ridiculous things like this, so they fire an Access Violation exception and VirtualDub crashes in the ASUS codec.

I don't know why people have this driver installed under a Windows NT platform, since it's obviously incompatible, but I'm going to try to code a workaround for it in V1.4.8 now that I have the codec (not) working on my system.  In the meantime, the best workaround I can think of is to remove the ASUSASV1.DLL codec, since it will cause crashes in programs that attempt to enumerate codecs in the system.

Incidentally, someone left this string in the module:

VIDC.SAMP:Sample 32-bit Decompression Driver

 10/19/2001: Influx of hardware and software

Nothing works better on a geek than cool toys.

Back when I still ran Windows 98 and still actively used my miroVIDEO DC10 capture device, I used to be irritated at Pinnacle for for their lack of support, specifically drivers.  Today, Pinnacle's Germany branch sent me a miroVIDEO DC30plus and a Studio DVplus to aid in VirtualDub development.  I can't comment yet on the exact details of the arrangement, but I'm excited be able to work with these cards, particularly since the DC30plus has better video quality than the WinTV, and probably than the ATI All-in-Wonder as well.  The Studio DVplus poses more of a problem for me since I don't yet have any Firewire devices, although that can be fixed and it does have an analog output that could be some fun.  This fills out two major holes I had in my testing matrix -- a card with integrated audio, and IEEE-1394.  Thanks, Pinnacle!  Of course, being the pragmatic person that I am, I stuck them both in the same computer.

Actually, this means I have five capture devices installed in one computer: ATI AIW, WinTV, DC30plus, Studio DV+, and USB webcam.  And then there's the DC10, VideoMotion, and Rainbow Runner that I don't have installed....

On the software side, I recently purchased a copy of Connectix Virtual PC, and I love it.  It makes it tremendously easier to debug issues with Windows 95 or NT4.0, and in addition, its emulation support is way better than VMWare's.  The video updates are ten times smoother and don't leave junk on screen, and I can drag-and-drop files in and out of the VM.  It's better for running DOS games -- Virtual PC emulates FM as well as PCM sound, although not very well, and I managed to play a whole game of Master of Orion in Windows 2000, with music.  Rebel Assault runs well too.  The most disgusting evidence of its power, though, was when my coworker got bored and decided to try running VMWare inside of a Virtual PC session.  It must have taken ten minutes for "Phoen" to appear on screen in the VMWare window, but it actually works, and that cinched it for me.  So far, the only thing I know of that doesn't run in Virtual PC so far is Virtual PC itself (stupid autodetect) -- I'll have to try a Playstation emulator sometime.  Both Bleem! and Virtual Game Station cause VMWare to die with a thread panic message, and I'm curious to see how VPC fares.  One hint, though: Virtual PC absolutely hates PIO hard disk transfers, so if you get it, turn on DMA on the guest OS hard disk driver as fast as you can.

 9/24/2001: Subtitler V2.1 and user interfaces

I haven't updated in close to a month, but I'm still here.

Subtitler V2.1 has been released and is available from the filters page.  I finally bit the bullet and rewrote the text processing code to handle DBCS properly and to render text in Unicode.  In case you don't know, most of the Win32 functions that take strings are available in both ANSI (SetWindowTextA) and Unicode (SetWindowTextW) versions.  Windows NT/2000 internally use Unicode and thus the ANSI versions all convert their text first, but Windows 95/98/ME has a different approach: it simply doesn't support most of the Unicode functions.  This turned out to be a pain because if you install the Internet Explorer Language Packs on that platform, TextOutW will draw Unicode text, but the ANSI function calls still won't recognize DBCS text.  Even better, you can get the width of Unicode text (GetTextExtentPoint32W) but the version that fits text to a given width (GetTextExtentExPointW) isn't supported.  So, under Windows 95/98/ME, I resort to calling the former one character at a time and adding up the results.  Slow, but it works.  I expect that when the time comes to put more advanced filters in VirtualDub, the subtitler will get merged into the mainline, since its rasterizer is useful not only for text, but for drawing any sort of odd-shaped region in general.  Of course, this is yet another thing that's far off.

The other thing I've been working on is some better way to handle UI.  VirtualDub currently commits the sin of doing filter configuration by having the filter pop up a dialog.  This is neither localizable nor portable, and it also has the problem that everyone needs to write their own Win32 dialog code.  My main complaint with the last item is that Win32 provides no help in linking items -- it's very common that you want a grouped set of controls to be enabled or disabled depending on a checkbox, or static text to reflect the value of a slider.  What I'm trying to do is design a portable API that has the following features:

  • Works completely in Unicode, even under Windows 95/98/ME.  I hate DBCS.
  • Provides controls that are automatically localized, such as OK and Cancel buttons.
  • Allows automatic linking between the contents of different controls.
  • Has automatic layout for positioning and sizing of controls.  (This is necessary for portability, but also makes resizable dialogs much, much easier to do.)

The last one is nasty because of two special cases: a static or checkbox control that can wrap text, and a vertical column of options that can flow into multiple columns.  I'm currently toying with a solution similar to Java's AWT, where each control spits out minimum sizes recursively up the tree and positions are then decided going down.  This unfortunately doesn't work for wrappable controls.  It looks like handling this case will require the use of heuristics to gravitate toward an "ideal" aspect ratio set by the client, but the details of this still escape me at the moment.  Due to difficulties like this, I'll likely have to continue to allow a way for filters to create their own dialogs.  This will be discouraged though due to the reasons outlined above.

One other puzzle that has plagued me in this is that controls in a Win32 dialog have a tendency to not redraw correctly when you move them short distances -- I've seen checkboxes jittering back and forth and OK buttons spewing on top of Cancel buttons while smoothly dragging a resizable dialog.  Neither WS_CLIPSIBLINGS nor DeferWindowPos() helped, although SWP_NOCOPYBITS did at the expense of a lot of flicker.  If anyone has clues to why moving controls leaves guano on-screen, I'm all ears.

 8/26/2001: VirtualDub 1.4.7 released

Wouldn't you know it -- I introduced another bug into the MPEG-1 decoder when I was fixing earlier bugs.  Specifically, this one is serious in that it prevents I and P frames from decoding properly during a preview or save.  Fortunately, I hadn't yet done anything else to the V1.4 mainline and so it was a rather simple matter to quick-release 1.4.7 to address this problem.  Please upgrade to 1.4.7 when possible.

Subtitler 2.0 is also now out on the filters page.  Direct Bezier-path rasterization has sped up rendering by a factor of 10-20, and a number of additional SSA features have been implemented, such as karaoke, scroll up, banner, and font encoding.  Note that the subtitler now requires an outline font, so TrueType will work fine, but there have been reports of issues with Postscript fonts.  Let me know how it works out.

Build 13130 (Version 1.4.7):
   [bug fixes]
   * Fixed MAJOR bug in MPEG-1 decoder that I introduced
     in V1.4.6 that caused I and P frames to decode
     improperly during a preview/save.
   * Corrected typos and resetting of "rounded" option in
     emboss filter (thanks to Donald Graft).

 8/21/2001: VirtualDub 1.4.6 released

So much for a quick release.

I had intended to release 1.4.6 quickly to correct the audio interleaving bug, but while working on the next generation subtitler (subtitler 2.0), I found a another bug in VirtualDub: it reports incorrect timings to filters when the source is an MPEG-1 file.  I didn't notice it until I added karaoke to the subtitler, and then spent an hour afterward trying to figure out why it was so jerky.  In the process of fixing that bug, I had to rip up a lot of code, and in the process of doing that I discovered why VirtualDub's "drop frames when behind" function doesn't help with Huffyuv -- it can't skip frame decodes.  Until now that is.  Subtitler 2.0 hasn't been released yet, but it's very close.

No, the new versions of warp sharp and filter factory are not out yet either -- I haven't had time to polish them up.  It actually takes a full day for me to release a new version of VirtualDub, with the need to update files, compile the archives, upload them to SourceForge, and to fiddle with the release system until the files actually appear.  Afterward, I get to update the website.  Adding insult to injury was the absolute dismal performance of my 56K modem, which I couldn't figure out until I ran tcpdump -i ppp0 on the Linux router, which revealed a deterministic IP packet corruption at the same place in my web connection.  Adding asyncmap 0 to the pppd settings cleared things up wonderfully, so now I have one less piece of computer equipment to swear at.  Did I mention I hate modems?  I hate modems.

Final reason for delay: never let anyone introduce you to a new anime series when you are trying to get work done.  I've been listening to the Vandread OST for two days straight.

I'm going to switch gears on V2.0 again and attempt to merge the V2.0 framework directly into V1.4.6, sans Nina (processing engine) and Rydia (capture engine) -- there are too many nice features in V2.0 libraries that I need and it's becoming too much of a pain for me to maintain V1.4, even though I want to. So I'm going to do some housework instead.  I'm sure this will irritate Nando to no end, because he keeps Nandub fairly up to date with the official VirtualDub line, and doing this is going to make his next merge a horrendous pain in the (#*&$(, but it has to be done.  Rydia is about halfway done and could probably be merged in with not too much work, while Nina will replace VirtualDub's core and is far from being finished.  It's very, very slow, but I'm getting there.

Build 13110 (Version 1.4.6):
   [features added]
   * Enhanced error concealment in MPEG-1 video decoder
     to reduce picture spew on errors (NOT THE PARSER).
   * "Drop frames when behind" can now drop frames before
     the decoder.  This helps with Huffyuv playback.
   * Capture-mode noise reduction now works with UYVY
     video as well.

   [bug fixes]
   * Fixed that blasted Audio Interleaving bug I introduced
     in V1.4.5.
   * Added sample skip support for audio converter and
     amplifier filters, to prevent long delays when using
     subsets with them.
   * 'Save WAV' now truncates the file if the file you're
     saving over is bigger than the new data it's being
     replaced with.
   * Fixed frame output display not updating when attempting
     to display same frame after changing filters.
   * Fixed audio interleaving dropping out after a preview.
   * Read errors no longer appear interactively, blocking
     batch operations.
   * Attempting to shift in capture mode from 'preview with
     histogram' to overlay mode no longer switches to
     preview mode instead.
   * Fixed problem with hardware accelerated preview in
     capture mode with some ATI video cards.
   * No more of "1057% complete" in Job Control.
   * Changed some of the more embarrassingly bad error
     messages.

 8/3/2001: ATI...

Without a doubt, ATI has the most distinctive seven-hour video card installation I have ever seen.

I recently picked up an ATI All-in-Wonder Radeon in order to replace my aging NVIDIA TNT2 Ultra and to diagnose some of the strange problems people have been having with ATI hardware.  I swap video cards frequently as part of my job, so I turned off my system, replaced the TNT2 with the Radeon, turned it back on, and started installing the drivers and software under Windows 2000.  My first source of amusement was the warning from the ATI MMC software, which said that my system had problems which could impair my DVD playback performance, the least of which being that I have no DVD drive.  The system then rebooted, so that the display drivers could load.

A nice, deep blue bugcheck screen announced that the kernel could not load driver portcls.sys.  Great.  Reboot into safe mode, find portcls.sys, rename it to portcls.sys.disabled, and reboot.  I had to do this once when the Adaptec CDR driver prevented my system from booting.

Can't load emu10k1.sys.  Something tells me that neither of these two drivers is the problem.  Well, maybe it's a conflict.  Restore portcls.sys, turn off the system, pull all cards except the Radeon, and reboot.

Same thing.  Well, safe mode again, kick out the ATI driver entry, and try again.  System boots, login screen appears.  Login.  New hardware found, installing ATI WDM TV Audio Crossbar...  KMODE_EXCEPTION_NOT_HANDLED in ntoskrnl.exe.  Maybe the newest drivers off ATI's site will help?  Nope.  DirectX DV update?  Nope.  As you can imagine, by this time I'm not very amused.  Time to pull the Radeon and reinstall the TNT2.

portcls.sys {could not load driver}.  Okay, screw amused.  I'm pissed.

To make a long story short, I did get the Radeon working, but I had to reinstall Windows 2000 to do it.  (Removing the NVIDIA drivers did not help.)  I've worked with NVIDIA, Matrox, S3, 3DFX, and lots of other brands of video cards, and this is by far the most painful installation I've ever seen.  I figured that if a Kyro II and Voodoo Banshee can work in a multi-monitor configuration under Windows 98 (they do), then I should be able to swap between two recent AGP video cards without problems.  Nope.  Well, now I know why they made so many products under their "Rage" moniker.  Time from first card installation to first stable system running 16-bit Radeon video: seven hours.

Now that the rant is over....

The Radeon's video overlay quality is impressive.  My TNT2 used to do bilinear around version 1.9 of the Windows 98 drivers, but ever since 2.08 NVIDIA fouled up the vertical filtering and the overlay has looked horrible.  (As many of you know, I complain about this daily.)  The GeForce2 cards do full horizontal/vertical bilinear.  Radeon, however, does what looks like 4-tap bicubic in both axes of luminance, which results in a very nice image compared to the GeForce.  It's hard to tell about chrominance -- it looks like the chroma upsampling quality is poorer, but it's hard to tell without writing code to specifically test.  I found the bugs in VirtualDub 1.4.5 that were preventing it from doing DirectDraw-accelerated preview during capture on ATI hardware, so 1.4.6 should fix problems there.

And now, the meat: how to get VFW capture working with ATI MMC 7.1 under Windows 2000.  (Usual disclaimers apply: experts only, your fault and not mine if anything goes wrong.)

First, install DirectX 8.0a, the DirectX 8 DV update, and Windows 2000 Service Pack 2.  SP2 is mandatory, because it includes a file that you may not have.  Once you have it installed, check for a file called \WINNT\ServicePackFiles\i386\vfwwdm32.dll.  Copy it to \WINNT\System32\vfwwdm32.dll, if a file by that name doesn't already exist there.

Next, open up Registry Editor (regedit.exe), and drill down to:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\MediaResources\msvideo

Create a key called MSVideo.VFWWDM, and in it, create the following entries:

Name Type Data

Description REG_SZ Microsoft WDM Image Capture (Win32)
Driver REG_SZ vfwwdm32.dll

The Microsoft VFWWDM wrapper should now appear as a usable capture device in VFW-based capture programs.  Another method is to try the following strings in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion:

Name Type Data

drivers.desc\vfwwdm32.dll REG_SZ Microsoft WDM Image Capture (Win32)
Drivers32\msvideo REG_SZ vfwwdm32.dll

If msvideo already exists, use msvideo1, msvideo2, etc.  With this method you will most likely get two video capture entries, one that works and one that doesn't.  If this occurs, check to see if the MSVideo.VFWWDM key has been created; if it has, back out the second patch and apply the first.

I have not attempted to do this under Windows 98 SE, but if you happen to have vfwwdm.drv or a similar file, you might try adding it to [drivers] in system.ini as msvideo=vfwwdm.drv or similar.

The surprising part about this is that once you get the wrapper going, the performance is actually not too bad: I get 720x480 UYVY, compressed to Huffyuv, at 29.97 fps with about 50% CPU usage.  That's about on-par with what I get from my WinTV.  The WinTV overlay occasionally causes hangs with the Radeon, but I'm using an old version of the WinTV drivers (3.02), and in any case, Preview works fine.  So, with my webcam, that makes three capture devices in my system now.  Trust me when I say that VirtualDub is designed to work with multiple capture devices installed.

 8/2/2001: I am a moron

First, I can't help but wonder why I am receiving a number of emails that begin with

Hello Phaeron,

since I don't recall ever saying or implying that my email address was based on my real name.  It could be the default for some mail clients, but I would think that would lead to a number of emails prefaced with an intelligent "Hello abuse," or "Hello info."

Second, in an earth-shattering motion, I have decided that since bswap and xadd are too good to pass up, that when V1.5 is finished, VirtualDub will no longer support the 80386.

Third, there is a major bug in 1.4.5 -- audio interleaving is turned off whenever you preview.  This is a very easy bug to work around since you simply have to turn it back on before you save, but if it becomes enough of an irritation you might want to back down to V1.4d until I release 1.4.6 to fix the problem.  As usual, there is no need to install or deinstall VirtualDub, so you can simply rename the executables, stick them all in the same directory, and switch back and forth between them at will.  A source code fix has been posted in the KB for those who can use it.

Fourth, there is also a major bug in the filter factory that someone pointed out to me: code generation around the scan statement and around loops is very, very broken.  Specifically, the compiler has a habit of, oh, not generating P-code for entire blocks.  The problem is that the parser stage doesn't properly handle the fact that for loops decompose to an initializer statement and a while statement, and if there is another statement following, the parser replaces the while with it.  (This transformation is correct because filter factory doesn't support continue.)  It has since occurred to me that a language similar to MATLAB's, which supports algebraic syntax for large array and matrix transforms, would be far more useful than the C-- I have now -- in particular I am a big fan of the conv2 function -- but I currently don't have any framework for matrix operations, so that'd be another thing I'd have to write.  It'd be great for prototyping, though.

Fifth, I somehow shipped out warpsharp with the crappiest sampling mode, a slow bilinear sampler written in straight scalar C.  I've since re-enabled the MMX bicubic routine -- although it gives much more of a speed improvement than a quality one -- and more importantly, discovered that boosting the blur and lowering the ceiling on the bump map improves the quality.  I think the results of the improved version suit Inuyasha quite well, or at least, so the fifty billion trials I ran on the opening would indicate.  I still can't figure out why the filter overreacts to horizontal edges, although I suspect it might have something to do with my octagonal 2D-distance approximation.  By the way, the result of warpsharp on non-cartoon material is usually amusing.

Sixth, subtitler crashes if a line is very, very short horizontally.  This has to do with the hacky way that I'm doing the border, which is basically convolving the font image with a solid, round brush.  Unfortunately the round brush (pillbox) is not separable, so I decompose the brush into horizontal spans, and then use some really hairy bit manipulation with lookup tables to do the horizontal expansions quickly.  It is the last step that is crashing, and although I've been able to fix it, what I really need to do is what I wanted to do in the first place: retrieve the text outline from GDI, widen it, and rasterize the antialiased border directly from the bezier curves.  When I first tried doing this, I didn't know how to rasterize bezier curve outlines (I thought it required solving the y-equations for the possible three solutions of t), so instead I tried having GDI convert the text paths to regions.  Unfortunately, when you do this, GDI replaces each bezier with a single line, and, well, the result looks gross.  Since the subtitler works in 8x8 antialiasing, dropout control and hinting isn't really necessary, so I might take a whack at this again sometime, doing it directly from the paths.  This is especially attractive since it would also permit fluid rotation and movement of antialiased text.

I'm probably going to be releasing 1.4.6, and updated versions of the above filters in a few days.

On a side note, I'm getting an alarming number of bug reports from people who are having VirtualDub crash in the DivX 4.0 beta codec.  It appears that there are a number of places in the codec that are attempting to use instructions that are only supported on the Pentium III/4 and Athlon, specifically pmulhuw, without checking if the CPU supports it.  This is not a bug in VirtualDub, even though it is VirtualDub that is bringing up the crash dump.  Most of the bug reports are for 4.0b1 and 4.0b2, but I have one already for 4.0b3, even though it was supposed to be fixed.  Note that VirtualDub's disassembler does not understand Pentium III instructions, so the crash dump usually looks like this:

01023e0e: pxor  mm7,mm3
01023e11: psubw mm6,mm2
01023e14: psubw mm7,mm3
01023e17:       <-- FAULT
01023e19: lock 
01023e1c: clc
01023e1d: paddusw       mm6,mm5
01023e20: paddusw       mm7,mm5

The bug reports for this need to go to the DivXNetworks developers, not me -- they closed up the source, so it's up to them to fix it.

 7/18/2001: Vidomi issue resolved

I would have reported this yesterday, but it was too late for me to prepare by the time I found out.

Yes, folks, it's true.  The Vidomi encoder has been released as free software under the GPL, thus ending the conflict -- despite my reminders that the conflict could have been ended by dropping the GPL linkage, the makers doggedly insisted on becoming part of the GPL community!  The FSF has verified the current implementation GPL compliant as well; it's not the same as holy penguin pee, but it's more than good enough.  This arrangement is possible thanks to the time invested by Eben Moglen of the FSF and Dean Kaplan of SloMedia, who spent much time negotiating, stomping out misunderstandings in the license, and hammering out a solution. Some of you think the GPL is not a very good license, but I would like to point out that the FSF definitely puts their money where their mouth is -- their help in rectifying the conflict here was invaluable.

I think this calls for a celebration.  Now, I'm not too fond of booze, and it would be irresponsible for me to encourage others to drink and code, so let's celebrate this the way free software advocates should: by releasing code!

Warp sharp [warpsharp.zip] [warpsharp-src.zip]

This VirtualDub filter sharpens edges in an image by using warping techniques to warp pixels toward edges, making them sharper and crisper.  The algorithm was described on a web page somewhere that also had a GIMP script-fu implementation of it; this filter isn't based on the script-fu, but I'll freely admit that I didn't come up with the idea.  It's handy to apply after a enlarging resize filter to crispen the edges (although it doesn't make the result look better if you try reducing afterwards).  Oh yeah -- bad things happen if you run this and your CPU doesn't support MMX.

Filter factory [filtfactory.zip] [filtfactory-src.zip]

This VirtualDub filter allows you to write your own filters on the fly in a stripped-down version of C.  It needs a lot of work, but it will do if you want to do simple stuff like mask off the lower four bits of each pixel channel (i.e. out = in & #f0f0f0;).  You'll need to ask me for how to use it, until I can write docs.  I really should have named this one "why I don't write compilers for a living."

Mapconv and verinc [buildtools-src.zip]

These tools are used to autoincrement VirtualDub's build number and generate the virtualdub.dbg file from the link map generated by Microsoft LINK.

...

Hmm... something's missing here... oh yeah.

VirtualDub 1.4.5 [download page]

This was intended to be V1.4d hotfix 2, but I later realized that (a) "1.4d hotfix 2" was stupid versioning, and (b) if I used hotfixes to fix bugs, what were the letters for?  So I abandoned the lettering and hotfixing, and just made it 1.4.5.

Besides the usual round of bug fixes, one of the more exciting features in this version (IMO) is that I've backported the experimental UYVY/YUY2 overlay system from VirtualDub 2.0 back to V1.4.5.  This new system has two major advantages:

  • If you are capturing two fields, you can choose to preview only one of them.  This halves the amount of data that the CPU has to blit.
  • YCrCb to RGB conversion is done in hardware on the video card, and the data is transferred via DirectDraw instead of GDI.

What is the purpose of this?  The purpose is that, if you are capturing in YUY2 or UYVY, you can now get a blown up (near full screen) preview for about 40% less CPU power!  This is enough of a difference on my system that I can now apply noise reduction or similarly simple capture filters on the fly at 640x480, something I wasn't able to do before.  I'm rather embarrassed to say how I implemented it, actually.  Those of you who have worked with the Video for Windows capture system should realize by now that I did something nasty to do this -- I'll let you look at the source to find out for yourself what I did.

Also, the capture system now tells you how much of a timing correction it is applying to the video, in the form of a new "VT adjust" statistic.  Ideally, the number of "dropped" frames you have should be very close to this value, divided by the frame time in milliseconds.  If this number goes off the scale, VirtualDub's timing correction is going nuts.

Finally, I threw in an additional filter as a bonus: field bob.  This filter is most useful when combined with Avisynth's SeparateFields or VirtualDub's MJPEG field split -- it bobs even fields and odd fields by sub-scanline distances, resolving the global jitter between the two when the fields are displayed as sequential frames.

Build 12903 (Version 1.4.5):
   [features added]
   * Added DIV5 as yet another MS MPEG-4 V3 hack.
   * Experimental support for hardware UYVY/YUY2 hardware
     overlay when Preview display mode is used in capture.
   * The BT8x8 tweaker is now modeless and periodically
     reasserts your settings as long as it is up.
   * Added workaround for a buffer overflow problem in
     Huffyuv.
   * Fast recompress now works even if no decompressor
     is present (i.e. YUY2 -> MJPG).
   * Added workaround for broken AVI files with negative
     chunk sizes in the AVI header block.
   * New filter: field bob.

   [bug fixes]
   * Fixed menu problems under 95/NT.
   * Recompressed executable with newer version of UPX
     -- should fix NAV problems.
   * Added short-circuit code for AVI parser to avoid
     bombing on crud at end of some files.
   * Fixed broken 16-bit mono to 16-bit stereo
     conversion.
   * Filters are no longer reset when scrolling via
     keyboard shortcuts (Jason Haitsuka).
   * Levels filter now saves Y/RGB setting properly.
   * Fixed capture window vanishing with "stretch to
     window" set and "info panel" unchecked.
   * Fixed some problems with the hex editor.
   * Fixed the cropping dialog from coming up with
     the post-crop size.
   * Changed histogram in Levels filter to use luma
     instead of RGB, and removed bilinear filtering.
   * Video timing is now propagated properly through
     lagged filters (temporal smoother).
   * Script variables may now have numbers in their
     names.
   * No longer crashes if you specify a path without a
     filename on the command line.

 6/24/2001: The great DirectShow adventures

First, I've heavily updated the online capture documentation, so those of you who do analog captures may want to take a peek.

As some of you have guessed from the error message below, I am indeed in the process of coding DirectShow-based (WDM) video capture for VirtualDub 2.0.  The error message was actually due to my attempt to use std::basic_string instead of std::string -- which I didn't find out until I tried the offending code under GCC 2.96 -- but the fact still remains that there are a lot of bugs in the C++ front end of Visual C++ 6.0.  The vast majority of the bugs are related to templates, and you can read about the zillions of them in the Bug++ of the Month column in Windows Developer Journal.

As for DirectShow, a.k.a. ActiveMovie, a.k.a. Netshow, a.k.a. Quartz....

DirectShow is rather interesting to work with, once you chuck the original docs and go straight to the DirectX 8 help file.  On the good side, DirectShow is adept at automatically constructing rendering graphs to save a file or display video from a file or capture input.  On the bad side, DirectShow requires you to construct the graph yourself if you need to do anything else.  Similar to other Microsoft DirectX APIs, this requires a lot of calls to construct filters, find pins, and connect pins, any call of which can fail.  This leads to the traditional "phalanx of if statements" paradigm of coding, or some variation hidden under macros.  (Assuming you are a good programmer and actually pay attention to return values.)

The tricky part at this point is an idea I had for 640x480 YUY2 optimization.  One of the problems with VirtualDub 1.4d is that it relies on AVICap to do the on-screen display, and this display must be in Preview mode if you want to view your video when capturing 640x480 on a BT8x8 chip due to hardware limitations.  (I have added the details of this to the online capture documentation.)  VirtualDub provides its own MMX-optimized YUY2 codec to convert the video, but this still requires a YUY2->RGB conversion, followed by a rather painful GDI blit to the screen via DrawDibDraw.  A faster way to do this would be for VirtualDub to hook the preview callback and do the conversion directly to the screen, or even better yet, a YUY2 hardware overlay that can be stretched for free.  This is what I plan to do for VFW mode in V2.0.

Thankfully, as with AVICap, DirectShow takes care of most of the work, and a simple call to RenderStream() automatically adds whatever converters are needed to spit the video out through the Renderer.  The Video Renderer is rather adept and can not only take advantage of DirectDraw surfaces and blits, but can also use hardware overlays.  This offers the carrot of being able to simply hook up the Video Renderer straight to the capture pin of the device, and basically getting an overlay for free.

And if you try this with the capture driver set to YUY2, you will get an AVI Decompressor stuck in the middle and a bland RGB blit.  It took a lot of digging into the docs, experimentation with GraphEdit, and tinkering with source to a sample DirectShow filter to figure out what was going on.

The first problem is that, inexplicably, when the Video Renderer requests a YUY2 connection for the overlay, it does so with a negative biHeight value.  This is illegal according to the Microsoft docs, but the MPEG-1 decoder filter accepts it.  However, when the VFW capture filter wrapper sends YUY2 through, it doesn't invert biHeight, and the two mismatch.  The second problem is more serious.  The Video Renderer always starts in RGB mode and then requests a dynamic format change into the overlay's YUV format.  This has the unfortunate consequence of killing the overlay in the capture scenario because if the VFW filter is started in YUY2 it cannot dynamically switch to RGB and vice versa.  I'm going to have to write a DirectShow filter to fit in between the capture filter and the Video Renderer for this to work, because the AVI Decompressor filter isn't smart enough to bypass data if the output format becomes the same as the input.  The frustrating part about DirectShow is that the dynamic negotation between the pins tends not to be transitive, to the point that if you simply stick an Infinite Pin Tee Filter between the MPEG-1 decoder and the Video Renderer, you get a different display.

As some of you have discovered, the NBCi download page that had the hotfixes is down.  The page got taken down and tactly replaced with a WAREZ404Error.html page without notification, and they never gave me any explanation as to why.  (I'm curious as to how I managed to warez my own GPL program.)  I'm planning on releasing Hotfix 2 soon, though, so this won't be too bad.  I'll probably add it to the SourceForge site.

 6/13/2001: @#&$^&(%!

--------------------Configuration: Rydia - Win32 Debug--------------------
Compiling...
CapSys_DirectShow.cpp
I:\projwin\VirtualDub\Rydia\source\CapSys_DirectShow.cpp(51) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1794) 
         Please choose the Technical Support command on the Visual C++ 
         Help menu, or open the Technical Support help file for more information
Error executing cl.exe.

VirtualDub.exe - 1 error(s), 0 warning(s)

 6/11/2001: UYVY, YUY2, YV12, I420...

Some of you have been reporting splotchy video with YUV formats such as UYVY and YUY2.  It turns out that the culprit is a driver that comes with Windows 98 SE called msyuv.dll; it converts UYVY, YUY2, YV12, and YVYU to RGB, but it has two problems.  The first is that it only outputs 16-bit RGB, giving you the splotchiness (banding).  The other is that it assumes the source luma (Y) component is full-range, giving you a washed-out look.  If you are having this problem, replace msyuv.dll by installing Huffyuv; this will give you 24-bit color conversion for UYVY and YUY2, and it will be significantly faster.  For raw YUY2, you can also open the AVI file directly in VirtualDub, but the color quality will be slightly lower since VirtualDub doesn't interpolate the chroma.

I still haven't gotten around to finishing the V1.4d updated docs for the filter SDK, unfortunately.  If anyone wants to write a filter with a lag between input and output, email me and I'll send you details. 

By the way, people, beta generally means "fixing bugs in feature complete code," while alpha is not yet even to that point.  Which is why I tend to be rather disinterested when people send me crash reports involving the ProjectMayo OpenDivX 4.0 alpha codec.  Beta code may crash; alpha code is pretty much guaranteed to.  I don't know why so many of you are being dumb and encoding material with an alpha codec anyway, but that's your business.

With regard to email, two news items.  First, I've placed a 200K per-email limit on my mailbox.  I've gotten tired of people emailing me 5MB BMP attachments consisting of most of their desktop and a tiny message box in the middle, or sending me AVIs or ZIPs I didn't ask for and can't use anyway, thus adding to my download time and adding to my 28MB Inbox.  Hopefully more people will learn how to crop and compress their images, and ask before indiscriminately sending files all over the place.  Second, my UCSB account is going to expire very soon.  Anyone who is still using the ucsb.edu address to contact me needs to switch over to the virtualdub.org address at the bottom of the page.  This unfortunately includes all users of V1.3c, so please spread the word to those that refuse to upgrade for, um, various reasons.

As for the quiz below....

The killer is the rounded conversion from float to int:

dst[i*stride] = floor(0.5 + s[i]);

Both the floor and the implicit float-to-short conversion are killers -- on x86 CPUs, the conversions are most commonly coded by flipping the FPU rounding mode, which incurs a hit of about a hundred cycles per conversion.  To give you some idea of how bad this is, a single 8x8 IDCT incurs 64 of these conversions, for a hit of around ~6000 cycles.  VirtualDub's scalar IDCT runs in about 1100 cycles, and the MMX IDCT takes around 350... and these include MPEG motion compensation.  No amount of tweaking the rest of the code is going to produce the speedup that removing this bottleneck is going to do.  (There are a number of ways to avoid the painful conversion, but unfortunately, I think all of them are non-portable.)

Interestingly enough, although it is not the correct answer, folding sqrt2 * 0.5 together does provide a small improvement, because the compiler is prohibited from making that particular optimization.  (a*b)*c and a*(b*c) are algebraically equivalent, but may produce slightly different results in floating-point arithmetic.  Associativity went bye-bye when we went digital, and unfortunately, this makes life hard for the optimizer.

Oh well.  You learn something every day, and I never depend on compiler optimization anyway....

 5/25/2001: programming schtuff

Legal junk aside, time for a pop quiz.

This is a piece of working early alpha code from VirtualDub 2.0's MPEG-1 decoder.  What is the largest performance bottleneck in it, which is intended to do a one-dimensional, eight-point inverse discrete cosine transform (IDCT)?  The algorithm is the basic definition, subdivided to two levels using the Lee decomposition.  Assume that the function is called with a stride of 1, round is true, DT is of type short, ST is of type double, and that all compiler optimizations are enabled.  This corresponds to the output column transform; the row transform as already been applied with template arguments <8, false, double, double>.  You are looking for a significant bottleneck here -- enough to slow the MPEG-1 decoder by a factor of three.

template<int stride, bool round, class DT, class ST>
inline void crappy_idct_1D(DT *dst, const ST *src) {
    static const double coeffs4[4]={
        2.0*0.98078528040323043,
        2.0*0.83146961230254524,
        2.0*0.55557023301960229,
        2.0*0.19509032201612833,
    };

    static const double coeffs2[2]={
        2.0*0.92387953251128674,
        2.0*0.38268343236508984,
    };

    static const double sqrt2 = 0.70710678118654752440084436210485;

    double t[8];

    for(int i=0; i<8; ++i)
        t[i] = src[i*stride];

    double s[8], u[8];

    s[0] = t[0];
    s[1] = t[2];
    s[2] = t[4];
    s[3] = t[6];
    s[4] = t[1];
    s[5] = t[3];
    s[6] = t[5];
    s[7] = t[7];

    s[6] -= s[7];
    s[5] -= s[6];
    s[4] -= s[5];
    s[4] *= sqrt2;

    // begin 4x4 IDCTs

    t[0] = s[0];
    t[1] = s[2];
    t[2] = s[1];
    t[3] = s[3];
    t[4] = s[4];
    t[5] = s[6];
    t[6] = s[5];
    t[7] = s[7];

    t[2] -= t[3];
    t[2] *= sqrt2;
    t[6] -= t[7];
    t[6] *= sqrt2;

    // 2x2 IDCTs

    u[0] = (t[0]+t[1]) * sqrt2 * 0.5;
    u[1] = (t[0]-t[1]) * sqrt2 * 0.5;
    u[2] = (t[2]+t[3]) * sqrt2 * 0.5;
    u[3] = (t[2]-t[3]) * sqrt2 * 0.5;
    u[4] = (t[4]+t[5]) * sqrt2 * 0.5;
    u[5] = (t[4]-t[5]) * sqrt2 * 0.5;
    u[6] = (t[6]+t[7]) * sqrt2 * 0.5;
    u[7] = (t[6]-t[7]) * sqrt2 * 0.5;

    // end 2x2 IDCTs

    u[2] *= coeffs2[0];
    u[3] *= coeffs2[1];
    u[6] *= coeffs2[0];
    u[7] *= coeffs2[1];

    t[0] = (u[0]+u[2]);
    t[1] = (u[1]+u[3]);
    t[2] = (u[1]-u[3]);
    t[3] = (u[0]-u[2]);
    t[4] = (u[4]+u[6]);
    t[5] = (u[5]+u[7]);
    t[6] = (u[5]-u[7]);
    t[7] = (u[4]-u[6]);

    // end 4x4 IDCTs

    t[4] *= coeffs4[0];
    t[5] *= coeffs4[1];
    t[6] *= coeffs4[2];
    t[7] *= coeffs4[3];

    s[0] = (t[0]+t[4]);
    s[1] = (t[1]+t[5]);
    s[2] = (t[2]+t[6]);
    s[3] = (t[3]+t[7]);
    s[4] = (t[3]-t[7]);
    s[5] = (t[2]-t[6]);
    s[6] = (t[1]-t[5]);
    s[7] = (t[0]-t[4]);

    if (round) {
        for(int i=0; i<8; ++i)
            dst[i*stride] = floor(0.5 + s[i]);
    } else {
        for(int i=0; i<8; ++i)
            dst[i*stride] = s[i];
    }
}

If you want to play, please email your responses to quiz (at-sign) virtualdub.org.  This is not a contest with a prize, but I'm just trying to see how many of you are on your optimizing tippie-toes.   I have already fixed the huge bottleneck here, so I'm not trying to get free optimization out of my readers. :)

Hint: It's trickier than it looks.  Suggesting the LLM, AAN, or any other alternative, faster IDCT algorithm will get you zero credit (because it will be the wrong answer).

 5/23/2001: slashdot effect

It turns out my web hosting provider is in a different timezone than I am, so my weblogs just cycled and I have a nice graph of the slashdot effect.  I'm quite glad I switched over to delivering gzipped pages.

 5/23/2001: Welcome slashdot readers -- here are some clarifications on the Vidomi issue

I woke up today and found out that, according to slashdot, I was suing a company.  Wow, I didn't know I was doing that.  Maybe sleeping in late isn't such a good idea after all.  I always knew that if or when I ended up on slashdot, I would be finally and truly infamous.

Here are some clarifications, both to the article and various random comments I perused:

I am not currently suing SloMedia.  I consider this a last resort option that would likely be detrimental to both parties, and in addition, I would need support from another entity like the FSF to pull it off.  It looks like there might be a way to resolve the issue amicably without doing so and without comprimising the GPL; I am currently exploring those options.

I code according to the three golden rules: laziness, impatience, and hubris.  As a result, I like to write my own libraries instead of using other peoples' code, and as a corollary, I'm not particularly interested in seeing SloMedia's.  I have never demanded that the company relicense their proprietary code under the GPL, and I had no interest in using the GPL as a weapon (club?) to beat them over the head -- I merely asked that they remove my code.  I really have better things to do (like write more code).

The VirtualDub website is virtualdub.org; www186.pair.com/vdub is a non-domain alias to the site that I used to use but still works, and virtualdub.com is the result of a botched domain transfer on my part.  (Any of you who have domains under register.com can rest easy; it's likely easier for someone to file a lawsuit than to issue a fraudulent transfer with them on your domain.)  Please use the .org address; this is the address that is coded into the Help menu of current versions.

For general use, VirtualDub is licensed under, and only under, the General Public License (GPL), version 2 or later.  There is not and has never been a version licensed under the Library or Lesser General Public License (LGPL), and the disputed code in question was not encapsulated in a DLL by me.  The resampling and colorspace conversion code was first extracted and re-wrapped into FlasKMPEG (which is GPL'ed), and was then subsequently lifted from that and placed into a DLL by the Vidomi programmers.

If I remember correctly, my reverse engineering of the ASF file format structure took place after the DMCA was enacted but before the anti-reverse-engineering clause took effect, and between the filing and issuing dates for the Microsoft patent.  I will have to look up the exact dates, but ASF functionality existed in VirtualDub long before the infamous V1.3c release that will seemingly roam the Internet for eternity.  This is, unfortunately, the same ASF parser that ended up in the Linux avifile library in modified form -- so anyone using that library needs to be careful.  Frankly, I'm amazed my parser ever worked at all, given how nasty it was.

There are two distinct codecs which bear the DivX name: the original 3.11 alpha codec, and the new 4.0 "OpenDivX" codec.  Both are from the same person, Gej.  The 3.11a codec actually consists of two, the "Low-Motion" codec, which is a hack of MPG4C32.DLL 4.1.00.3917, and the "Fast-Motion" version, from MPG4C32.DLL 4.1.00.3920.  The relationship between the Microsoft and the 3.11a codecs can be readily verified by a binary compare, and the encoded formats are the same except for some operating parameter defaults, like bitrate, and a change in FOURCC code.  The OpenDivX codec is a new implementation of the real MPEG-4 standard based off of the MuMoSys reference codebase, and is not interoperable with the old 3.11a codecs -- neither can encode or decode each others' formats.  It is unfortunate that they share the same name, given that they are essentally independent.  To my knowledge, there is no codec implementation independent of Microsoft's codebase that can decode the MPEG-4 V3 data generated by it, and I don't think there have been any lawsuits yet for anyone distributing the 3.11a hack... although if you search the Microsoft media player group on Usenet you'll find the Windows Media programmers don't like it very much.  VirtualDub does not contain any special support for DivX 3.11a besides identication (nasty dialog), equivalence mapping to the MS codec, and general workarounds for some bugs that have been in all MS MPEG-4 codecs since the original build 2700 Netshow release, particularly those related to the bitrate control constantly resetting itself.

All recent versions of Microsoft LINK strip relocation information from executables and fixed-link the binary at 00400000 unless instructed otherwise; VirtualDub is linked this way.  Thus, you can only load one such binary as a library, and even that requires that you link your own executable well above that address.  This causes some problems for alternate execution environments, like Wine, especially if the OS in question normally uses that virtual address range.

 4/17/2001: VirtualDub 1.4d KB updated and hotfix 1 available

The Knowledge Base has been updated with problem reports for V1.4d.  Norton Antivirus is turning out to be more of a pain in the @*#^$*& than I'd anticipated -- I've gotten problem reports that suggest it may impede capture performance as well.  Now I'm beginning to remember why I ditched NAV.  I'm actually rather curious as to how NAV is doing its trace.  API interception would be acceptable, but I hope it's not running VirtualDub as a debugger because the Win32 debug APIs are known to, uh, drop thread synchronization events occasionally, which causes threads to deadlock.

I figure it's better to release a buggy fix than none at all, so I've released VirtualDub 1.4d hotfix 1. You'll need to download it from the download page I set up at NBCi, but from there on you just unzip it over regular V1.4d.  The changes are rather trivial but I recommend that you not install it unless you are experiencing one of the specific problems that it addresses, since it may have introduced regressions into the codebase.  (A "regression" refers to the situation where adding a code patch causes a previously fixed bug to reappear.)  For those of you who need to synchronize to the source code fixes (Nandub), the patched source code files have been included in a subdirectory, and can be popped in or Windiff'ed against the original source.

One final word: I appreciate all of the people who have properly followed the rules of the GPL when using VirtualDub's source code, and it's great that the modified and augmented code is being recycled back into the GPL community.  However, I've been seeing a problem in a couple derivatives that needs attention: when you copy someone else's source code file and modify it, you need to keep their original copyright notice, because you only own copyright on the modifications, not the original code.  Furthermore, third parties need to know who wrote the original code as well as the modified code, because if they want to request license exemptions they need to contact both parties.  What this means is that if you have this at the top of a source file:

// Swodniw - An operating system
// Copyright © 1999-2001 Foo, All Rights Reserved
//
// This program is free software....

You shouldn't simply replace the entire copyright block:

// Xunil - An operating system
// Copyright © 1999-2001 Bar, All Rights Reserved
//
// This program is free software....

I'm not terribly pedantic about the form of the copyright block in derived copies, since the derived software is also GPLed, but it is important that third parties know everyone who is involved.  Try to keep "VirtualDub" and "Avery Lee" in the notice, please. :-)

 4/7/2001: Menu funniness, Norton Antivirus, and the IDCT

I finally tracked down the reason for some of the menu funniness that people have been experiencing with VirtualDub, usually resulting in very, very large most recently used (MRU) lists. It appears that, at some point in the evolution of the Platform SDK, Microsoft extended the the MENUITEMINFO structure in a non-compatible way. Windows 98 and 2000 do not have a problem, but Windows 95 will fail some menu calls -- and GetLastError() still returns zero. As a result, VirtualDub has difficulty maintaining its MRU list and will display a variety of strange symptoms. This is purely a cosmetic issue, although you may need to restart if the list gets too big. VirtualDub 1.4d is built against newer Win32 includes than V1.4c, which explains why the menu handling code broke, even though I didn't change it.

About the hex editor: uncheck "Read Only" on the Open dialog to enable editing.

Also, it appears that some versions of Norton Antivirus get suspicious about the UPX 1.04 executable compression used to reduce the size of VirtualDub.exe, and place the executable under some sort of trace until it finishes loading. The result is that, with NAV enabled, VirtualDub may take as long as 30 seconds to load! If you are having this problem, download UPX from the UPX webpage, unzip it, and decompress the executable:

upx -d VirtualDub.exe

Then, get another antivirus program.

I'm going to try to put out a hotfix release to fix the above two issues. Yes, Geocities did can my webpage, and I don't know why, but for now I've moved the stuff that was there over to NBCi. This means that virtualdub.com is now a dead link, so please spread the word that the VirtualDub website is at virtualdub.org.

For those of you interested in the inverse discrete cosine transform (IDCT) and its affect on MPEG decoding quality, especially with FlasKMPEG, try the IDCT challenge. Also relating to IDCTs, Intel has also finally released the complete source code to its AP-922 IDCT algorithm at its SSE2 notes page as AP-945. AP-922 only provided code for the column transform of the FDCT and the row transform of the IDCT, which was, well, less than helpful, as everyone had to derive their own versions of the missing halves. It turns out that Intel's code is not very different from the column code I derived for VirtualDub, being substantially similar in accuracy and instruction count. (For those who may have tried, VirtualDub's MMX IDCT code is not directly transplantable to other decoders. The shuffles at the beginning of the row transform were removed and integrated into the zigzag order of the MPEG-1 and MJPEG coefficient decoders.)

Finally, some have been asking where to find the driver necessary to use the BT8x8 tweaker feature of V1.4d. The files you need are part of the binary distribution of dTV, at http://deinterlace.sourceforge.net, and you should copy dTVdrv.dll, dTVdrv95.vxd, and dTVdrvNT.sys into VirtualDub's directory. The feature might not work under NT/2000 if you don't have sufficient permissions. Be careful when using this feature, since unlike dTV, VirtualDub uses the card's capture driver as well, which will overwrite the settings at times. It's best to tweak the chip right before you begin to capture.

 3/29/2001: VirtualDub 1.4d released

If you haven't figured it out already, I enjoy writing, although I'm not an English major and couldn't write fiction to save my life.

NitohRyu -- as we'll call him -- insisted that I release VirtualDub 1.4d for a very important new feature, and three weeks after he asked, here it is! I'll put the changelist at the bottom, because it's long. Although this release has a lot of bug fixes in it, more than even 1.3 had, there is one important new feature: VirtualDub now has a hex editor! Yes, folks, this is one of the few hex editors that will change a FOURCC in a 17GB file, quickly and easily. It also has a RIFF block scanner, so those of you who have really broken AVI files can take a shot at restoring them from scratch, assuming you have a good knowledge of the AVI format. There are also updates to the scripting interface and filter API that need documentation. I'll try to get the updated docs out soon. I also encourage capture enthusiasts out there to try the new temporal smoother filter in post-processing -- this is a new FIR filter that takes advantage of the new frame lag support, and it seems to be much more effective at noise reduction than the old recursive, temporal-axis filters various people had previously made.

Of course, now that I've gotten V1.4d out, I can resume making fun of him for being a Java programmer.

I promised myself a while back that V1.4d would be a bugfix-only release, but that obviously didn't hold, and I ended up throwing most of the features people wanted that weren't too difficult to implement. Obviously, a lot of features and bugfixes didn't make it in, either, and I apologize for that, but I only have so much time on my hands, and I really don't want to make any big changes to the V1.4x series, because it would prolong a codebase that truly needs to die. The other factor that you must understand is that I do this in my spare time, for fun, as perverse as it may seem. Although I do want to put out a stable and feature-rich product, I'm not out to make the ueber-video-processing program. If I wanted to do this, there are a large number of shortcuts that I could take, such as licensing third-party code, closing the source so I could sign NDAs/agreements for encoding formats, etc., and it would likely lead to a broader product. It would also be a giant pain to maintain, and more importantly, it wouldn't be mine. I have a tendency to reject large third-party libraries or patches for the sole reason that I like to understand things and write my own code, and sometimes that leads me down the slower path. So be it, especially if it means I can avoid releasing a quilt. VirtualDub wouldn't be as advanced and coherent as it is today if I didn't take the time to learn how video actually works from the zillions of mistakes I made trying to roll my own. That doesn't mean I don't appreciate or accept third-party suggestions or solutions, but I do tend to be a bit more random than you'd expect in incorporating them, especially when it comes to big interface changes -- I attribute some of my interface apathy to having been brought up on AmigaDOS.

Sometimes people ask me to implement features in VirtualDub because they're too cheap to buy Premiere, or even shell out piddly $$ for AVI_IO. That's fine; I'm a cheap bastard too, occasionally. To some extent, however, this comes about because of a general misunderstanding of why the GNU General Purpose License (GPL) exists, and why I release VirtualDub under it. Free software is not about popularity, and it's not about undercutting or out-developing proprietary solution providers. The free software movement is about the freedom of the software, which the GPL ensures by placing no restrictions on use and protecting your right to modify and redistribute; it doesn't matter if the author kicks the bucket or tries to close up the product, since nothing short of making the software illegal (*cough*DeCSS*cough*) will inhibit your ability to copy and evolve the version in your possession. I highly suggest reading the documentation at the Free Software Foundation; general consensus is that Richard M. Stallman is a nut, but I'm increasingly convinced that he's a nut with the right ideas. It is true that I have considered jumping ship from the GPL for V2.0, but that's more due to pragmatic issues (interoperability) than philosophical ones, and I don't think I'm going to do it.

As for the evolution of VirtualDub, I've horribly underestimated the ETA to V2.0, and chances are it won't be complete for at least a year. V1.5 looks like it might be sooner, since Nina can now do smart rendering (mixed DSC and full rendering), and the major work now is to port filters, MPEG-1, and capture support, which aren't as bad. So, please have patience, learn about desktop video and signal processing while you wait, and enjoy the ride!

Oh, and one more thing: I'm now using "The Bat!" from RitLabs for email. It's pretty good, and has just about everything I've wanted, although there are a couple of rough edges that could be smoothed with multiple account support. What's funny is that when I asked for email client suggestions, I got about twenty responses, and about seventeen or so were for The Bat! -- which tells me that RitLabs is either doing something right, or everything else is horribly wrong. I'm more inclined to believe the latter, since there are truly some bizarre clients out there. For some reason, it seems an increasingly alien idea that people would want to send text, and just plain text, in an email.

Build 12665 (Version 1.4d):
   [features added]
   * Added HFYU (Huffyuv) to list of codecs that do not
     have delta frames.
   * Added code to prevent AngelPotion from improperly
     accepting all formats for which there is no valid
     codec in the system.
   * You can now tweak some choice BT848/878 registers
     (i.e. full luma range!!) if you copy the dTV drivers
     into the VirtualDub program directory.
   * Hex viewer now has limited editing capability.
   * Added option to squish luma range for YUY2 captures
     on the fly to alleviate "white out" problems.
   * Filters can now lag behind, like IVTC.
   * Resize filter now supports interlaced resampling.
   * You can now also select one channel rather than
     mix both channels when converting stereo to mono.
   * Frameserver mode hides the main window now.
   * One word: amplify.
   * Avisynth 1.0b+ errors are detected as errors, so
     VirtualDub won't produce processed errors anymore.
   * Type-1 DV files are supported.  VIDEO ONLY!
   * New "temporal smoother" filter.
   * Some more keyboard shortcuts added, and tooltips
     for the main screen for all you wimps. :)
   * Alt-Left and Alt-Right scan by 50 frames, and the
     default step value for paging in the position
     trackbar is also now 50 frames instead of two
     inches.
   * Additional values and methods are exported to
     scripts.
   * Preview mode can now do interlaced display as well
     as progressive display.  (Requires very fast CPU!)

   [bug fixes]
   * Fixed problem where capture mode wasn't adequately
     correcting for sound card error.
   * Audio section of File Information no longer counts
     up indefinitely on Avisynth scripts.
   * Avisynth scripts shorter than 12 bytes can be
     opened.
   * Spill drive thresholds are properly treated as
     megabytes and not kilobytes.
   * Fixed a couple of issues in the crash handler that
     were causing useless double-crash dumps.
   * Fixed dwSampleSize=0 incompatibility with audio
     streams from Canopus utilities.
   * Hex viewer now works in Windows 95.
   * Rekey warning no longer appears in batch mode.
   * IVTC settings are now saved properly in scripts.
   * Added workaround for codecs that crash on zero byte
     frames (ASV1, VCR2).
   * Filter crop dialog now shows the right size input
     frame (the image is still approximated, however).
   * Added checking for uncompressed frames to avoid
     crashing on short frames.
   * "Rekeying not specified" warning no longer appears
     for video formats known to have no keyframes.
   * Fixed 24-bit MMX YUY2-to-RGB conversion.
   * Subpixel accuracy problems and the occasional line
     of garbage on the right border from the resize filter
     have been fixed.
   * MRU list is no longer case sensitive.
   * Fixed precision issue when doing high upsampling,
     such as 8KHz to 44KHz.
   * Fixed video codec handle leak in video compression
     dialog.
   * Loading an OpenDML segment no longer keeps legacy
     files from appending after it.
   * Fixed crash during multisegment video capture under
     high CPU load.
   * Added workaround for disk drivers that do not support
     unbuffered I/O.
   * MJPEG split was causing some crashes if you sourced
     a multisegment AVI clip.
   * AVI output function wasn't padding frames to quadword
     boundaries properly in capture mode.
   * Hex viewer (editor) no longer locks files.

 2/25/2001: New documentation up

While up at 1 AM in the morning, I asked myself, what can I do? Document VirtualDub, of course! Yes, I'm weird. You can find it through the Documentation link at the top. I think I'll go to bed now.... zzzzzzzzzzz

 2/19/2001: Capture timing, email clients, and Nina

First, yes, I do know this is the year 2001, thanks to the half-dozen or so people who told me my last update said 2000.  I'm absent-minded.

With the help of a fellow user, I finally tracked down the reason for capture audio desyncs.  It's because some of you have crappy sound cards!  VirtualDub's audio timing correction works by converting the current audio position to a video frame, and adding or subtracting 1ms if the video stream is more than one frame off.  It works this way because the timing measurements VirtualDub gets from the audio and video sources are hardly precise, and the timing correction is deliberately gradual to accommodate noise.  However, since the correction only occurs at the end of an audio block, and each audio block is at least half a second long by default, the correction is normally limited to 0.2% and will fail if the audio and video clocks are skewed by more than that.  I had an SB AWE32 when I wrote that code, which was accurate to a tenth of that amount (0.002%, or 44094Hz on a 44100Hz target), and my current SBLive! is even more accurate, which is why I didn't see the problem myself.  The knowledge base has been updated with the workaround as well as entries for some other known problems.  Note that the "lock video stream to audio" checkbox only works for compatibility mode, and compatibility mode capture disables half of VirtualDub's capture functionality, so don't use it unless you have to!!  In particular, compatibility mode disables dynamic timing correction, so the best you get is static timing correction, which works by changing the FPS on your video stream -- which usually guarantees that any edits will be problematic with the funny frame rates that result.

On another note, I hate Outlook [Express].  Absolutely despise it.  I'm sick and tired of getting email from Outlook users which is not word-wrapped and has the original message pasted below the reply, instead of standard 70-something column wrapped text with quoted material preceded by a > at the top of the message.  As a result, I have to unwind and word-wrap the mess, and Pegasus Mail's fscked word wrapping code doesn't help.  The only thing worse is HTML-only email, which I immediately trash.  I still haven't found a good email client; Pegasus Mail is better than most, but has a lot of quirks and bugs, especially in its editor.  I rejected Eudora, Outlook, and Outlook Express primarily on one reason: they don't word-wrap your response until you hit send, which virtually guarantees that the message that gets sent looks nothing like you intended.  The latter two, of course, also failed on their inability to do any sort of standard quoting properly.  Agent was almost everything I wanted, except that it didn't handle multiple mailboxes without switching configurations, which eventually made it a pain to use for email (I still use it for news).  It's almost getting to the point that I want to write my own mail client, but I already have precious little spare time as is, and more than enough concurrent projects already.

While I'm on totally random subjects....

A couple of people emailed me with guesses as to why I named the V2.0 engine Nina, and of course, they were completely wrong.  The funniest was from the author of Avisynth, who guessed the name "Nina Inverse-Telecine," but of course was still way off.  Actually, this was the inspiration for the name (apologies to Capcom):

Nina

In addition to being an anime otaku, I'm also a fan of computer RPGs, and this is Nina Windia from Capcom's Breath of Fire II, for the Super Nintendo.  Needless to say, I was pretty disappointed when found out that Nina had become some sort of pixie girl in BOF3, and that she was actually pretty worthless in battles; BOF4 is worse, with all characters looking rather bland.  I've also played and completed Final Fantasy IV-IX and Tactics, as well as a few anime RPGs (Sailor Moon AS, Ranma, and MKR).  I suppose that makes me a bit of an RPG freak, but my friends already knew that I was a nut.

 1/21/2000: Attaching VBR MP3s to AVI files

A modified build of VirtualDub recently got posted on the Internet that allows you to multiplex externally encoded MP3s with a video track, to produce an AVI file with VBR (variable bit rate) audio.  Although this is not an official build, it sort of works, with only one problem...

VBR audio is invalid in an AVI file.

The equation that determines audio synchronization in an AVI file is  time = audio_sample * block_size / average_bytes_per_second , with block_size and average_bytes_per_second being constant over the entire AVI file.  AVI does support VBR streams, but as the Canopus AVI problem showed, the dwSampleSize=0 value doesn't work for audio streams (see below).  Couple that with the fact that for the Fraunhofer MP3 format, block_size = 1 byte per sample, and you can see a small problem: AVI forces a rigid relationship between bytes and time.  This formula is also the only relationship -- the placement of audio blocks in the file relative to video blocks, or interleaving, makes absolutely no difference in audio sync, and this why "audio skew correction" is the only setting in VirtualDub's audio menu that makes a difference.  Yes, you can have VBR audio in an AVI file, and it will play.  You'll also find that the greater degree of VBR used, the worse the audio sync can get in local areas.  Windows Media Player is especially sensitive to fast variation of bitrate, and you can end up with variations in video playback speed as a side effect of the VBR.  I think you can see now why I've not added the ability to mux VBR audio into the mainline codebase.  Please do not ask me for this feature, because I'm not going to add it.

Sharp observers will point out that MPEG layer III audio is inherently VBR to some extent.  This is, in fact, the key to realizing how bad of hack MP3-in-AVI is.  MP3 has three features that make it difficult to use in AVI:

  • Bitrates can be switched on the fly, thus modifying the frame size, since frames are always 1152 samples (MPEG-1) or 576 samples (MPEG-2).
  • To hit an exact bitrate at 44.1KHz, the padding bit is toggled periodically, adding or subtracting a single byte off the size of each frame.
  • Unused space in a frame can be used by later ones.  This is called the "bit reservoir."

The Fraunhofer codec's solution is to avoid varying bitrates, to lie by saying that the compressed block size is one byte, and to silently accumulate bytes until a complete frame can be decompressed.  This breaks rigid synchronization at the AVI level, but it works well enough during playback because the ratio of compressed to decompressed data is pretty regular for constant-bitrate streams.  Use a VBR stream, however, and you can interfere with smooth buffering in the player.  Also, this lie gives you really lousy edits, because the MP3 stream has a granularity hundreds of times worse than the 1-byte block size indicates, and the codec has to discard the fragments that remain.  As a result, you can have a terrible time trying to offset the start of an MP3-compressed audio track in an AVI.  I recommend not compressing to MP3 until after all your edits are done, or else you can get glitches at the edit points.

 12/31/2000: Canopus, VirtualDub 1.5, Linux, and VirtualDub 1.4c build 0

Yes, as a lame after-Christmas/New Year's present I've decided to give you all a big news update. (grin)

Through the help of a fellow Canopus user, I finally tracked down the reason why VirtualDub coughs up blood on Canopus AVI files.  It seems the Canopus utility sets the AVI file's audio stream dwSampleSize value to zero.  This value ordinarily indicates that the stream has variable size chunks with one sample for chunk, and as a result VirtualDub tries to load about 10,000 times more samples into memory than it should.  Microsoft AVI parsers apparently ignore this value for auds streams and use the nBlockAlign value instead.  I can't find anything in the Microsoft documentation that indicates that setting this value to zero for audio is anything but illegal, but I guess if the AVIFile parser allows it then VirtualDub will have to as well.  As a workaround for the current version, set the file type in the open dialog to "AVI (compatibility mode)."  One of these days I'm going to have to write a white paper on parsing AVI, since it's become somewhat of an art.

Speaking of V1.4d, I don't think I've told everyone what my future plans are for VirtualDub.  As it stands, I'll probably be releasing a V1.4d for bugfixes, and that will be the last release for the current codebase.

Last release!???

For a while now I have been working on the next generation processing engine for VirtualDub 2.0, codenamed "Nina."  (Extra points to anyone who correctly guesses why I picked that name, and no, I don't know anyone named Nina.)  V2.0 is the acclaimed "Real Soon Now(tm)" vaporware release that will support multiple sources, audio filters, input/output plugins, and better SMP performance.  It became all too apparent early on in development that V2.0 would take too long, so I then plucked the working branches into a new tree, V1.5, which would target the V1.4c feature set.  This does not mean that V1.5 will not bring new features (to say nothing of bugs), but it will not support multiple sources.  V1.5 is not anywhere near completion either, but it is capable of processing files right now and has reached the "viability threshold" where it does something more or less reminiscent of what it is supposed to eventually do.  Once I finish and release it, I'll be able to bring the V1.4x series to a halt, which has gotten to be so much of a mess that I can barely maintain it, and then I'll be able to develop V1.5 into V2.0 much more smoothly.

You know, maintaining VirtualDub is so much work that some days I almost feel like finishing my Ranma 1/2 fanfic instead, but I prefer to embarrass myself in C++ rather than in English. :)

Another feature that I've been toying around with is the possibility of a Linux port.  (Sorry BeOS and Mac users, but BeOS is a very small user base, and I hate Macintoshes.)  One problem is my extensive Linux experience, not having the slightest clue how to write a simple X application and still typing "mv /mnt/*" by accident on occasion.  The other, far more serious problem is that the V1.4c codebase is very non-portable, even to x86 Linux.  I am writing V1.5 with much greater portability in mind -- not that it will compile to libc5-i386 out of the box, but so that anyone who attempts a port won't run screaming after seeing the source.  (VirtualDub does sort of run under Wine, but I'd be mortally embarrassed to release a winelib port.)  Codecs are a problem, but I think MPEG-1, Motion JPEG, RGB, various YUV formats, and Huffyuv would be doable, along with Microsoft Video 1 if you're a glutton for punishment.  I'm not promising anything though, since I don't want to end up like my buddy who thought he could change the current directory in Java.  I'm also keeping localization in mind, although don't expect my monolingual self to do any localized versions.

Maybe I'll call the Linux port V2.4 and see if I can beat the linux-kernel people.... nah.

There appears to be a new build of VirtualDub V1.4c floating around that supports ASF the same way V1.3c did.  This is not an official release, one telltale sign being that it has a build number of 0.  (Don't bother asking me for it.)  The major problem with this is that some people have confused the modified build with the official build and sent me crash dumps from it, which are useless since I didn't compile the modified build.  If you distribute a modified VirtualDub, please mark it as modified! I don't know where it came from, and I don't mind that someone modified the code -- that's why it's GPL! -- but I can't help but notice that the source code is not getting distributed, again.  For all you ASF freaks, that's why in the first place you had so much trouble finding the V1.3c source code that I couldn't redistribute, although obviously someone had it.  Open source code effectively makes a program immortal.  I'm not condoning the distribution of infringing code, but part of the reason I distribute VirtualDub as open source is that if anything happens to me, my website, or my hard drive, VirtualDub will still exist in a form that can be continued.  Those of you who are familiar with emulation probably know that several emulation projects have died outright because the author's hard drive got erased or damaged, and the program's source code was not released.  It is vitally important that the source code to an open source application be available, even if 99% of the people who download the program do not grab it.  The source code is far more important than the binary, since the binary can be produced from the source but not vice versa.  This is one of the many reasons open source applications are preferable, why others should be encouraged to release source code, and yes, why Richard M. Stallman is not crazy.

 12/01/2000: VirtualDub scripting language document

People finally bugged me enough to document VirtualDub's scripting language, so I've written a description of VirtualDub script commands.  Also, I finally updated the links page with the changed Indeo link, another MPEG encoder (TMPGEnc), and Avisynth.

Finally, I have the virtualdub.org domain now!  I haven't gotten around to updating all the references yet, though.

 11/06/2000: Updates

I've been incredibly busy with other things during the past month, so I haven't really had time to work on VirtualDub, much less keep up with the never-ending flood of email.  Ordinarily, I don't particularly care too much what codecs people use, with or without my program, but there's one codec that's so bad I absolutely have to speak out about it:

If you have the "AngelPotion Definitive codec" installed on your system, uninstall it!

Here's a few facts about this codec:

  • Despite what the website says, AngelPotion is an MPEG-4 V3 hack like DivX.

    The APmpg4v1.apl file that AngelPotion installs in your system directory is actually a compressed version of Microsoft's MPG4C32.DLL.  This file is decompressed to a file in your temp directory and opened as a codec, with the AngelPotion driver acting as a shim between the client program and the driver.  Builds around ~400 had an unmodified version of build 3688, the Windows Media Tools 4.0 beta version of the MS codec; as of the latest build (702) the file's resources have been modified to look like "APvcLib" but it is still the MPEG-4 V3 codec -- look at it in a hex editor.  AngelPotion is the same as the Microsoft codec, produces the same compressed video format, and is no more legal than DivX.  You can change the FOURCC of an AngelPotion file to DIV3 or MP43 (MPG4C32.DLL build 3688 only), and it will decompress fine.

  • AngelPotion stockpiles driver copies in your temp directory and loads multiple copies.

    AngelPotion decompresses and opens a new version of the MPEG-4 V3 codec every time it is opened.  If you check your temp directory, you will see a buildup of files that all have the exact same file size.  Check the process space of a video program that has scanned for video codecs, and it is not unusual to see four copies of the MPEG-4 V3 codec loaded from the temp files.

  • AngelPotion can keep Avisynth 0.3 and other applications from opening AVI files, of any video format.

    The driver illegally patches the biCompression input format field of certain ICDecompressQuery() calls to MP43 and does not change it back, making subsequently queried codecs think the input format is MPEG-4 V3.  (In newer builds, the FOURCC is different because the underlying driver has been hacked, but the problem still exists.)  The codec arbitration code of Avisynth versions before 1.0 beta will trigger this problem and cause Avisynth to mistakenly use AngelPotion to decompress any video formats for drivers loaded after it.  This is not a bug in Avisynth.  The same erroneous behavior also can cause any application using AVIStreamGetFrameOpen() with a requested output format to try to use AngelPotion to decompress the wrong video formats, even uncompressed RGB video. The usual symptoms are a crash in the temp file that AngelPotion loads as a driver, or completely incorrect decompressed video.

  • AngelPotion is suspected of causing crashes on application close.

    I have received reports of, and seen, crashes caused by AngelPotion on application exit.  Build 3688 of the Microsoft codec, which some or all versions of "APvcLib" are, is known to be occasionally unstable.  This makes AngelPotion unstable as well.

If you send me a crash dump from VirtualDub with the AngelPotion codec loaded in memory, I will tell you to retest the problem with AngelPotion uninstalled and then delete the dump.  There is no way I can guarantee VirtualDub's proper functioning in any case if AngelPotion is loaded, even if it is not being used.  I am no fan of DivX, but I would rather you install DivX rather than this piece of crap.

  • To remove AngelPotion under Windows 95/98/ME:

    Edit system.ini and delete or comment out lines of this form under [drivers32]:

    VIDC.AP41=APmpg4v1.dll
    VIDC.DIV3=APmpg4v1.dll
    VIDC.DIV4=APmpg4v1.dll

  • To remove AngelPotion under Windows NT/2000:

    Open regedit, drop down to HKEY_CURRENT_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32, and delete or rename these keys:

    Key nameValue
    VIDC.AP41APmpg4v1.dll
    VIDC.DIV3APmpg4v1.dll
    VIDC.DIV4APmpg4v1.dll

 9/23/2000: VirtualDub 1.4c released

VirtualDub 1.4c has been released, which fixes all known stability issues to date:

I've received a generous amount of donations, and I'd like to thank everyone who donated or even considered donating -- enough has been donated now to cover the overcharge, with some left over to go into the web fund.  (Note: I haven't actually received the money yet, due to having started right after the end of a payment cycle, but I can live with the delay.)  So let me return the favor by at least dumping off some goodies:

Build 11759 (Version 1.4c):
   [features added]
   * New filter: box blur.
   * Levels filter can now work in YCC space to avoid
     altering saturation.
   * Interface notifies you when multiple input files have
     been loaded.
   * "Add filename extension" is now on by default (this
     won't change anything for those who already saved
     their settings in Preferences).
   * Added workaround for broken DivX audio hacked codec
     which comes up with no name above the PCM codec in
     the audio codec list.
   * Added check and warning for DivX drivers.
   * VirtualDub now warns and deletes multisegment files
     already on disk on a save, preventing old and new
     saves from mixing.

   [bug fixes]
   * Lengthened some job system buffers to handle long
     filename issues.
   * Levels control now sets the cursor -- no more I-beam
     when trying to change input levels.
   * Fixed a problem which caused multisegment saves with
     video compression to break.
   * MPEG layer III correction is now disabled on multi-
     segment saves to avoid errors on join.
   * Fixed interleaving when saving a file with IVTC
     enabled and audio interleaving in per-ms mode.
   * Job system no longer writes out filenames as all
     C-escapes.
   * Fixed the noise reduction in capture mode, AGAIN,
     since I brought the old code into 1.4b by mistake.
   * Fixed a potential crash with the levels filter.
   * Fixed "copy output frame" command when an in-place
     filter with clipping is last in the filter list.
   * Fixed a nasty frameserver bug that caused crashes on
     certain audio reads.

This build fixes the major multisegment and frameserver crash/corruption bugs.  Two new filters have been introduced with this release; one is a fast, high-radius blur, and the other is a levels filter that doesn't affect saturation.  Increasing saturation does bad things to post-compression quality, and the new levels filter works by default in (Y, R-Y, G-Y, B-Y) space instead of RGB space.

Last, but not least, subtitler V1.3b is out.  It's actually been on the FTP for a few days, but I hadn't gotten around to updating these pages.  This subtitler fixes a smart wrapping bug that caused hangs under specific multi-line dialogues.  No additional functionality has been added, so unfortunately, font embedding and encoding still aren't supported.  Font encoding is quirky and probably violates copyright law in most cases anyway, so I'm not very inclined to support it.  Font encodings, maybe, but I haven't used them in SSA before so I'm not sure exactly how they work.


 http://www.virtualdub.org/virtualdub_news_old © 2000-2002 Avery Lee <phaeron at virtualdub dot org>