Current version

v1.10.4 (stable)

Navigation

Main page
Archived news
Downloads
Documentation
   Capture
   Compiling
   Processing
   Crashes
Features
Filters
Plugin SDK
Knowledge base
Contact info
Forum
 
Other projects
   Altirra

Search

Calendar

« October 2014
S M T W T F S
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Archives

01 Dec - 31 Dec 2013
01 Oct - 31 Oct 2013
01 Aug - 31 Aug 2013
01 May - 31 May 2013
01 Mar - 31 Mar 2013
01 Feb - 29 Feb 2013
01 Dec - 31 Dec 2012
01 Nov - 30 Nov 2012
01 Oct - 31 Oct 2012
01 Sep - 30 Sep 2012
01 Aug - 31 Aug 2012
01 June - 30 June 2012
01 May - 31 May 2012
01 Apr - 30 Apr 2012
01 Dec - 31 Dec 2011
01 Nov - 30 Nov 2011
01 Oct - 31 Oct 2011
01 Sep - 30 Sep 2011
01 Aug - 31 Aug 2011
01 Jul - 31 Jul 2011
01 June - 30 June 2011
01 May - 31 May 2011
01 Apr - 30 Apr 2011
01 Mar - 31 Mar 2011
01 Feb - 29 Feb 2011
01 Jan - 31 Jan 2011
01 Dec - 31 Dec 2010
01 Nov - 30 Nov 2010
01 Oct - 31 Oct 2010
01 Sep - 30 Sep 2010
01 Aug - 31 Aug 2010
01 Jul - 31 Jul 2010
01 June - 30 June 2010
01 May - 31 May 2010
01 Apr - 30 Apr 2010
01 Mar - 31 Mar 2010
01 Feb - 29 Feb 2010
01 Jan - 31 Jan 2010
01 Dec - 31 Dec 2009
01 Nov - 30 Nov 2009
01 Oct - 31 Oct 2009
01 Sep - 30 Sep 2009
01 Aug - 31 Aug 2009
01 Jul - 31 Jul 2009
01 June - 30 June 2009
01 May - 31 May 2009
01 Apr - 30 Apr 2009
01 Mar - 31 Mar 2009
01 Feb - 29 Feb 2009
01 Jan - 31 Jan 2009
01 Dec - 31 Dec 2008
01 Nov - 30 Nov 2008
01 Oct - 31 Oct 2008
01 Sep - 30 Sep 2008
01 Aug - 31 Aug 2008
01 Jul - 31 Jul 2008
01 June - 30 June 2008
01 May - 31 May 2008
01 Apr - 30 Apr 2008
01 Mar - 31 Mar 2008
01 Feb - 29 Feb 2008
01 Jan - 31 Jan 2008
01 Dec - 31 Dec 2007
01 Nov - 30 Nov 2007
01 Oct - 31 Oct 2007
01 Sep - 30 Sep 2007
01 Aug - 31 Aug 2007
01 Jul - 31 Jul 2007
01 June - 30 June 2007
01 May - 31 May 2007
01 Apr - 30 Apr 2007
01 Mar - 31 Mar 2007
01 Feb - 29 Feb 2007
01 Jan - 31 Jan 2007
01 Dec - 31 Dec 2006
01 Nov - 30 Nov 2006
01 Oct - 31 Oct 2006
01 Sep - 30 Sep 2006
01 Aug - 31 Aug 2006
01 Jul - 31 Jul 2006
01 June - 30 June 2006
01 May - 31 May 2006
01 Apr - 30 Apr 2006
01 Mar - 31 Mar 2006
01 Feb - 29 Feb 2006
01 Jan - 31 Jan 2006
01 Dec - 31 Dec 2005
01 Nov - 30 Nov 2005
01 Oct - 31 Oct 2005
01 Sep - 30 Sep 2005
01 Aug - 31 Aug 2005
01 Jul - 31 Jul 2005
01 June - 30 June 2005
01 May - 31 May 2005
01 Apr - 30 Apr 2005
01 Mar - 31 Mar 2005
01 Feb - 29 Feb 2005
01 Jan - 31 Jan 2005
01 Dec - 31 Dec 2004
01 Nov - 30 Nov 2004
01 Oct - 31 Oct 2004
01 Sep - 30 Sep 2004
01 Aug - 31 Aug 2004

Stuff

Powered by Pivot  
XML: RSS feed 
XML: Atom feed 

§ InterVideo, you suck

I always have problems debugging DV capture in VirtualDub because I don't actually have a capture device that outputs it. Recently, I got the idea to insert the DV Video Encoder filter into the DirectShow filter graph, which would then create DV on the fly. So I set the magic registry key to use it as the transform filter, started a debug session in Visual Studio, and set the capture device.

VirtualDub vanished.

Did it crash? Nope, no exception dialog. Stack overflow? Nope. Failed exception unwind? Nope. The debugger just showed all threads in the process exiting with return code 2. That's not a failure code.

Long shot: Set a breakpoint on {,,kernel32}_ExitProcess@4... what do you know, breakpoint hit. WTF? Who's causing my process to exit?

(Read more....)

§ Fun with animated GIFs

For no particular reason, I sat down this weekend and wrote animated GIF import/export routines. Animated GIFs aren't that common anymore -- at least, for non-obnoxious uses -- but I don't have any tools to manipulate them and hadn't ever worked with the format. Besides, the last time I'd experimented with LZW compression was in high school, where I got around 10 bytes/sec on a 7MHz 68000. I was pretty sure I could improve on that since I actually know about hash tables this time.

It's now apparent to me why the GIF image format became so popular: it's much simpler and easier to implement than either JPEG or PNG. JPEG is difficult because of the inverse discrete cosine transform (IDCT) and marker stuffing in the bitstream; PNG's Deflate compression uses two nested layers of Huffman trees in addition to sliding window compression. The LZW compression used by GIF, on the other hand, can be implemented in a reasonably performant fashion with about a page of code for the encoder and decoder each. All told, I'd say it only took about a day each to get the GIF decoder and encoders working, which is astonishing when you consider that GIF is still competitive with PNG for some types of images. It helps that the original Compuserve GIF specification is well-written and precise, although the PNG specification is even better in these respects.

It also helps that I cut a bunch of corners in the initial implementations, but it works on the test images so far....

Now, any export code must of course be appropriately tested:

01/15/2007  04:54 PM       170,706,854 SHUFFLE! OP.gif

640x360, 2183 frames, 24 fps. And no, I'm not uploading it.

Internet Explorer did manage to open the 163MB animated GIF, but froze for about a minute at 100% CPU during the load. It then only managed to play the video at about 8 fps and only up to about a quarter of it. That's disappointing, but reasonable.

Mozilla Firefox also had difficulty opening the GIF file. A lot of difficulty, in fact:

[Task manager - Firefox at 1.5GB]

(FYI, my laptop has 1.2GB of memory.)

Amazingly enough, although it swapped a lot, it did manage to play the entire video, at full frame rate, and without crashing. So, if you want to play your favorite anime openings in a horrendously inefficiently encoded fashion and in 256 color glory, Firefox is clearly better than Internet Explorer. I might try writing an animated GIF larger than 4GB next, just to see what happens.

(Read more....)

§ One video codec to break everything

How does one video codec break every other video codec in the system?

Simple, really.

The way that video codecs work in Windows is that each one is queried in turn and asked if it supports the compressed video format. If a codec says "yes," then that codec is used to decode the video. Otherwise, Windows proceeds to the next video codec down the line, until it either finds one that can handle the format or runs out of video codecs. The details are different between Video for Windows and DirectShow, but the general idea is the same. This provides a great deal of flexibility, because a video codec can decode more than one format. Some MPEG-4 video codecs, for instance, can helpfully also decode uncompressed YCbCr formats that are difficult to find dedicated codecs for, like YV12.

It also adds a bit of fragility, in that occasionally a video codec's decompression query routine acts as follows:

Q: Do you support video format....
A: Yes!
Q: Uh, I didn't tell you the video format. You really support this?
A: Yes!

The errant video codec then proceeds to capture every video format that comes its way, and happily barfs whenever it gets any format other than the one it was supposed to handle. Since the shell media extension in Windows XP uses video codecs to try to get basic information and thumbnails for videos, Windows Explorer can now crash if you hover over the wrong videos. And guess what... the common File-Open dialog is based on an Explorer view, so it too can crash in any program.

As a result, one bad video codec can cause every other video codec in the system to fail to function. So far, I have encountered three video codecs that do this. It's even more fun when you realize that querying a codec involves loading it, so a codec that crashes on load due to Data Execution Prevention (DEP) crashes, anti-debugger checks, etc. can cause even more... fun.

For those of you who are considering or have worked on plugin APIs, this has some implications for API design. Querying every codec provides maximum flexibility to the video codecs, but also increases the fragility of the system -- if anyone goofs up, the whole thing breaks. Now, none of the three video codecs I've found so far were actually trying to decode multiple formats, but did so unintentionally. By having plugins provide some basic information that the API host can use to pre-filter queries, the system becomes more reliable, as it is much easier to make a single routine in the host reliable than a series of checks in all third-party plugins. It's also faster since you're not loading a ton of DLLs every time.

Those of you who read Raymond Chen's The Old New Thing blog may recognize the above problem as a variant on his "sure, we do that" story. Happily, the workaround is similar. What VirtualDub does is that it eschews use of the VFW ICLocate() function and instead manually enumerates and opens the video codecs, so it can directly control the query process. It then calls ICDecompressQuery() with a bogus compressed format and sees if the video codec bites. If the video codec takes the bogus format, then VirtualDub only uses that video codec if the compressed format is one that the codec says it can compress to; otherwise, it bypasses the codec and keeps going. You'll know if this happens because VirtualDub will display a warning on opening a video file with the name of the video codec that has the bug.

(Read more....)