none
AVI to BMP -- how to decompress the AVI file

    Question

  • I'm a newbie here, so hope this is in the right forum --> please let me know if I'm in the wrong place.

    0. Basic Need
    ----------------------
    My basic need is to figure out how to turn an AVI file that contains, say, 100 frames, into a series of 100 BMP files.

    The AVI file I'm working with runs for about 2.5 seconds. Most files I'll be working with will last less than 6 seconds.  I'm working with VB6. Essentially, my app takes the filename and path, opens the file, and "dumps" the AVI file into an array (type Byte). This takes a nanosecond (small file size helps, I'm sure).

    1. Background
    ------------------
    My first foray into this realm was with an actual BMP file. I found a spec for the header on the web. I parsed the header, and then created a copy of the file byte by byte. I then loaded the newly created file into a PictureBox control .. works fine.

    Next, I created 2 "cropped" images. The source is 90 x 700 pixels. By extracting a set amount from each pixel "row" (in triplets for RGB, or, actually, BGR as I came to learn), I created 2 new BMPs with reconfigured headers. Each new image is 90 x 180 pixels. Image-1 starts at the left of the source image. Image-2 starts at pixel 120, hence there is some overlap with image-1, by design. My eventual goal is to be able to determine the "overlap-zone" of two images by analyzing things at the pixel level, but more on that in the future. I got the two newly created images to appear in 2 additional PictureBoxes just fine.

    Now I am trying to accomplish the same thing with an AVI file. I've got the header and index decoded, and am about to extract the data, frame by frame. However, since the data is compressed, a given frame's worth of data will not "simply" comport to the RGB data for a BMP.

    Hence, my basic need to be able to decompress the file so as to turn it into a series of 100 BMPs.

    2. Some file specs
    -------------------------
    The AVI file is 1,513,048 bytes in size.
    The video image is 480 x 640 (height x width).
    Basic math: 480 x 640 = 307,200. As a BMP, 307,200 x 3 (for RGB) = 921,600 bytes.

    I have extracted the following offsets from the index:

    Frame 1: 328
    Frame 2: 62,994
    Frame 3: 67,868
    ...
    Frame 99: 1,486,244
    Frame 100: 1,500,470


    For each frame, the audio is a constant 1,158 bytes; the video size varies. Here is a sample:

    Frame 1: 61,492 bytes
    Frame 2: 3,700
    Frame 3: 15,624
    Frame 4: 14,976

    Obviously, these are hugely smaller than 921,600 bytes. Much compression has occurred.

    I'm not looking for free-ware to do this. I've checked on the web, and there is a ton of it. Call me a glutton for punishment -- but, I'd like to "build" this myself, from the ground up. Hence my current need for the algorithm to decompress.

    Any tips (or pointers to web links) would be most appreciated. Thanks

    Spoo
    • Moved by Reed KimbleMVP Tuesday, September 02, 2008 5:17 AM VB6 Question in VB Language Forum (Moved from Visual Basic Language to Off-Topic Posts (Do Not Post Here))
    Monday, September 01, 2008 5:25 PM

All replies

  • spoo said:

    I'm a newbie here, so hope this is in the right forum --> please let me know if I'm in the wrong place.

    0. Basic Need
    ----------------------
    My basic need is to figure out how to turn an AVI file that contains, say, 100 frames, into a series of 100 BMP files.

    The AVI file I'm working with runs for about 2.5 seconds. Most files I'll be working with will last less than 6 seconds.  I'm working with VB6. Essentially, my app takes the filename and path, opens the file, and "dumps" the AVI file into an array (type Byte). This takes a nanosecond (small file size helps, I'm sure).

    1. Background
    ------------------
    My first foray into this realm was with an actual BMP file. I found a spec for the header on the web. I parsed the header, and then created a copy of the file byte by byte. I then loaded the newly created file into a PictureBox control .. works fine.

    Next, I created 2 "cropped" images. The source is 90 x 700 pixels. By extracting a set amount from each pixel "row" (in triplets for RGB, or, actually, BGR as I came to learn), I created 2 new BMPs with reconfigured headers. Each new image is 90 x 180 pixels. Image-1 starts at the left of the source image. Image-2 starts at pixel 120, hence there is some overlap with image-1, by design. My eventual goal is to be able to determine the "overlap-zone" of two images by analyzing things at the pixel level, but more on that in the future. I got the two newly created images to appear in 2 additional PictureBoxes just fine.

    Now I am trying to accomplish the same thing with an AVI file. I've got the header and index decoded, and am about to extract the data, frame by frame. However, since the data is compressed, a given frame's worth of data will not "simply" comport to the RGB data for a BMP.

    Hence, my basic need to be able to decompress the file so as to turn it into a series of 100 BMPs.

    2. Some file specs
    -------------------------
    The AVI file is 1,513,048 bytes in size.
    The video image is 480 x 640 (height x width).
    Basic math: 480 x 640 = 307,200. As a BMP, 307,200 x 3 (for RGB) = 921,600 bytes.

    I have extracted the following offsets from the index:

    Frame 1: 328
    Frame 2: 62,994
    Frame 3: 67,868
    ...
    Frame 99: 1,486,244
    Frame 100: 1,500,470


    For each frame, the audio is a constant 1,158 bytes; the video size varies. Here is a sample:

    Frame 1: 61,492 bytes
    Frame 2: 3,700
    Frame 3: 15,624
    Frame 4: 14,976

    Obviously, these are hugely smaller than 921,600 bytes. Much compression has occurred.

    I'm not looking for free-ware to do this. I've checked on the web, and there is a ton of it. Call me a glutton for punishment -- but, I'd like to "build" this myself, from the ground up. Hence my current need for the algorithm to decompress.

    Any tips (or pointers to web links) would be most appreciated. Thanks

    Spoo


    Compressed video frames are often just deltas (changes to the previous frame).  Using your sample frame byte counts, Frame 1, at 61,492 bytes is probably a "key frame," where the data represents an entire image.  Frame 2, at 3,700 bytes is probably just the deltas (differences) needed to convert Frame 1 into Frame 2.  As a result, you can't just pull a frame out of the sequence of frames and decode it; You need to decode a sequence of frames, starting with a key frame.

    Seems to me that the easiest way to do this would be to "play" the video, pause at the desired frame, and then read the pixel data from the video overlay frame.  Seems to me that DirectX might be the right tool, but if you're going to use DirectX you should probably also consider using C++ rather than VB, since all the DirectX documentation is aimed at C++ programming.

    Getting documentation and support libraries for video codec's could be difficult.
    Monday, September 01, 2008 6:30 PM
  • Firstly, unfortunately, this is not the forum for VB6 questions. Secondly, this isn't really a language-specific question. The key (no pun intended) is to understand the AVI file format and what it does or does not contain.

    You will have to determine the encoding schemes involved in the AVI file. This can be easy or hard depending on how much math and data manipulation you can take on. This'll require the good old Google Search.


    Stephen J Whiteley
    Monday, September 01, 2008 6:46 PM
  • "but, I'd like to "build" this myself, from the ground up. Hence my current need for the algorithm to decompress. "
    Nah.  You really don't.  Spend your time learning a current programming language. To delve that deeply into video codecs you'll need C/C++.
    If you're really interested in Windows video, download the Platform SDK and learn to use graphedt.
     
    Monday, September 01, 2008 7:13 PM
  • Actually, you don't need to know anything about codecs, as long as DirectX will play the video format you are using, and as long as you can figure out how to access the DirectX Frontbuffer (which contains the uncompressed image data that is being displayed).  To play the video, reference DirectX and DirectXSoundAndVideoPlayback.  If anyone has any hints on how to access the Frontbuffer (clearly possible from C++, but I haven't figured out how to do it from VB2008 yet) any hints would be appreciated.
    Tuesday, September 02, 2008 7:57 PM