Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
96 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Contents
 Introduction
 Files
 Streams
 Processing
 Cleaning Up

 Printable version
 Discuss this article
 in the forums


Getting a Stream’s Info

A stream’s information is obtained simply through the use of this function.

AVISTREAMINFO info; if(AVIStreamInfo(pStream, &infoAudio, sizeof(info))) // error

Like the file’s info, this stuff isn’t essential for processing an AVI file. There are some things you can calculate from the structure members, but I’ve found an easier way to determine these values that’s described later.

Determining a Stream’s Format

Since a stream can be of numeral kinds, we need to know its format. First of all, we must know how long the format data is. The following code accomplishes that.

LONG lSize; // in bytes if(AVIStreamReadFormat(pStream, AVIStreamStart(pStream), NULL, &lSize)) // error
* Audio Stream Specifics

The format data for an audio stream is based on the WAVEFORMAT structure, but it may have a few extra data members at the end and a different structure name. You can tell what structure it is by comparing the lSize variable with the sizeof(WAVEFORMATEX) or sizeof(PCMWAVEFORMAT). These structures, and most others, simply extend WAVEFORMAT with a few extra bytes.

PCMWAVEFORMAT includes the important wBitsPerSample member, and WAVEFORMATEX includes both wBitsPerSample and cbSize. The cbSize member tells how many extra bytes are stored after the WAVEFORMATEX structure. The extra bytes are for non-Pulse Code Modulation (PCM) formats, if you want to support those. Usually you’ll only find PCM formats, but the code you’re about to see supports all of them.

We’ll accomplish that by reading in a chunk and casting it to a WAVEFORMAT pointer.

LPBYTE pChunk = new BYTE[lSize]; if(!pChunk) // allocation error if(AVIStreamReadFormat(pStream, AVIStreamStart(pStream), pChunk, &lSize)) // error LPWAVEFORMAT pWaveFormat = (LPWAVEFORMAT)pChunk;

Now that we know the audio format, we are better equipped to interpret the actual sound information in order to play it back. It’s not necessary to be familiar with the structure members just yet.

* Video Stream Specifics

The BITMAPINFO structure defines the format for a video stream. That structure contains one of the BITMAPINFOHEADER, BITMAPV4HEADER, or BITMAPV5HEADER structures, followed by the palette information if the image format is 8bits per pixel. Software for Windows 98 or Windows2000 should write the BITMAPV5HEADER, but for reading an AVI file we need to determine which version was stored in the file in order to be backward compatible. That’s easiest by allocating and reading it all in one chunk like we did with the sound format.

LPBYTE pChunk = new BYTE[lSize]; if(!pChunk) // allocation error if(AVIStreamReadFormat(pStream, AVIStreamStart(pStream), pChunk, lSize)) // error

The reason why that’s possible, is because each structure begins with the same information as BITMAPINFO, but adds a few extra members to the previous version. If you determine that you need these extra members for a project you’re working on, it’s easy to cast the data chunk over to the appropriate structure pointer:

// Only if you need to: LPBITMAPINFO pInfo = (LPBITMAPINFO)pChunk; DWORD biSize = pInfo->bmiHeader.biSize; switch(biSize) { case sizeof(BITMAPV5HEADER): // ... case sizeof(BITMAPV4HEADER): // ... case sizeof(BITMAPINFOHEADER): // ... };

The BITMAPINFO structure tells us a lot about the image format. It tells what type of compression is used, the frame size, bit depth, etc. That’s all the necessary information one needs when converting image data over to a GDI HBITMAP, MFC CBitmap, LPDIRECTDRAWSURFACE, or custom format.





Next : Processing