Click here to Skip to main content
11,920,772 members (55,423 online)
Rate this:
Please Sign up or sign in to vote.
See more: C++ C Multimedia
I'm working on a piece of code which is able to read a frame from an AVI file and extract its pixel data. So far, I can succesfully open the AVI file and read any frame, but something goes wrong when decompressing.
This is the code I use (with error checking left out):

AVIFileOpen(&pf, filename, OF_READ, 0);
AVIFileGetStream(pf, &ps, streamtypeVIDEO, 0);
AVISTREAMINFO strhdr = {0};
AVIStreamInfo(ps, &strhdr, sizeof(strhdr));
BITMAPINFO *bi_in, bi_out;
long biSize = sizeof(bi_out);
AVIStreamReadFormat(ps, 0, 0, &biSize);
bi_in = (BITMAPINFO*)malloc(biSize+sizeof(bi_out.bmiColors));
bi_in->bmiHeader.biSize = biSize;
AVIStreamReadFormat(ps, 0, bi_in, &biSize);
bi_out = *bi_in;
HIC hic = 0;
// Check if the data is already in a recognised format (i.e. Uncompressed RGB or YUY2)
if(bi_in->bmiHeader.biCompression != 0 && bi_in->bmiHeader.biCompression != mmioFOURCC('Y','U','Y','2')){
	hic = ICDecompressOpen('CDIV', 0, &bi_in->bmiHeader, 0);
	biSize = ICDecompressGetFormat(hic, bi_in, &bi_out);
	// Check if the codec decompresses to YUY2 by default
		case mmioFOURCC('Y','U','Y','2'):
			bi_out.bmiHeader.biBitCount = 16;
			bi_out.bmiHeader.biSizeImage = 
		case 0:
			bi_out.bmiHeader.biBitCount = 24;
			bi_out.bmiHeader.biSizeImage =
			// Check if the codec is able to decompress to this format
			bi_out.bmiHeader.biCompression = mmioFOURCC('Y','U','Y','2');
			bi_out.bmiHeader.biBitCount = 16;
			bi_out.bmiHeader.biSizeImage =
			if(ICDecompressQuery(hic, &bi_in, &bi_out) != ICERR_OK)
				return 0;
	ICDecompressBegin(hic,bi_in, &bi_out);
int in_buf_siz  = strhdr.dwSuggestedBufferSize;
int out_buf_siz = bi_out.bmiHeader.biSizeImage;
void *inbuf, *outbuf;
	inbuf = malloc(max(out_buf_siz,in_buf_siz));
// This is the buffer the pixels are going to be in
unsigned char *AVIbuffer = (unsigned char *)malloc(out_buf_siz);
	outbuf = AVIbuffer;
	inbuf  = AVIbuffer;
long size = 0;
AVIStreamRead(ps, frame-1, 1, inbuf, in_buf_siz, &size, 0);
// Decompress the data
	bi_in->bmiHeader.biSizeImage = size;
	ICDecompress(hic, 0, &bi_in->bmiHeader, inbuf, &bi_out.bmiHeader, outbuf);
// At this point, I access AVIbuffer to find the pixel values of the current frame (be it in RGB or YUY2).

The code succesfully reaches the end and doesn't give errors anywhere, but the pixel data isn't right. Occasionaly there is a good frame (like once every 300) and inbetween the frames are mostly empty (grey, with very low contrast, occasionaly with fragments of the pixel data).
The AVI files I have tried to decompress have 4CC's of DIV3, DX50 and XVID. I do have the correct codecs installed on my PC; Windows Media Player can read the AVI correctly.

Any tips on what to change would be highly appreciated.
Thanks in advance!
Posted 14-Dec-10 8:25am
Henry Minute 14-Dec-10 13:36pm
If you don't get a response after a reasonable time, it might be worth your while posting this in one of the more specific forums as a lot of the folks that follow there don't visit here. The Graphics forum, maybe (

If you do that, mention that you have asked in Q&A but got no response, give it a few hours first though.
aspdotnetdev 14-Dec-10 13:39pm
Don't worry, Henry, we look at the Q&A forums too :-)

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

I didn't look at your code, but from what you describe I think I know the problem. You are probably decoding the keyframes correctly. The other frames are likely offset images that, when combined with the preceding frame, produce the result frame. Different formats have different strategies for the offset images... some do an alternating offset with each frame is offset from the frame 2 before it (for example). The file format you are working with probably stores this strategy, or the strategy used is described in the document describing the format.
Henry Minute 14-Dec-10 16:58pm
Not all the 'experts' do. For example Luc rarely posts here.:))
Thaddeus Jones 14-Dec-10 14:20pm
Thanks for your fast reply, I think you're right about what the problem is.
I tried passing ICDECOMPRESS_NOTKEYFRAME as dwFlags argument of ICDecompress though, and it doesn't seem to have an effect. Should I do this differently?
aspdotnetdev 14-Dec-10 14:35pm
Not really sure. I haven't worked with code like this before... I am only familiar with formats in general. Maybe you are supposed to combine the keyframes manually?
Thaddeus Jones 14-Dec-10 15:11pm
After some more testing, I think I've found the solution. ICDecompress can decompress these frames, I don't have to do it manually. It only works however, if it's done in order; so at least the previous key frame and all frames between that and the requested frame have to be processed.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 415
1 phil.o 170
2 Dave Kreskowiak 155
3 KrunalRohit 134
4 F-ES Sitecore 130
0 OriginalGriff 6,778
1 KrunalRohit 4,530
2 Sergey Alexandrovich Kryukov 3,203
3 George Jonsson 2,815
4 Suvendu Shekhar Giri 2,181

Advertise | Privacy | Mobile
Web02 | 2.8.151120.1 | Last Updated 14 Dec 2010
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100