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):
AVIFileInit();
PAVIFILE pf;
AVIFileOpen(&pf, filename, OF_READ, 0);
PAVISTREAM ps;
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;
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);
switch(bi_out.bmiHeader.biCompression){
case mmioFOURCC('Y','U','Y','2'):
bi_out.bmiHeader.biBitCount = 16;
bi_out.bmiHeader.biSizeImage =
bi_out.bmiHeader.biWidth*bi_out.bmiHeader.biHeight*bi_out.bmiHeader.biBitCount/8;
break;
case 0:
bi_out.bmiHeader.biBitCount = 24;
bi_out.bmiHeader.biSizeImage =
bi_out.bmiHeader.biWidth*bi_out.bmiHeader.biHeight*bi_out.bmiHeader.biBitCount/8;
break;
default:
bi_out.bmiHeader.biCompression = mmioFOURCC('Y','U','Y','2');
bi_out.bmiHeader.biBitCount = 16;
bi_out.bmiHeader.biSizeImage =
bi_out.bmiHeader.biWidth*bi_out.bmiHeader.biHeight*bi_out.bmiHeader.biBitCount/8;
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;
if(hic)
inbuf = malloc(max(out_buf_siz,in_buf_siz));
unsigned char *AVIbuffer = (unsigned char *)malloc(out_buf_siz);
if(hic)
outbuf = AVIbuffer;
else
inbuf = AVIbuffer;
long size = 0;
AVIStreamRead(ps, frame-1, 1, inbuf, in_buf_siz, &size, 0);
if(hic){
bi_in->bmiHeader.biSizeImage = size;
ICDecompress(hic, 0, &bi_in->bmiHeader, inbuf, &bi_out.bmiHeader, outbuf);
}
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!