Reading uncompressed AVI file frame by frame into raw memory buffer?
-
As the title states, I am having problems reading uncompressed avi files in MFC. It works fine on some files and reads different data on some avi files. Here is the code-
pStream = g_GetAviStream(_T("D:\\Lab_Programs\\Matlab\\output.avi"), &frames, &fWidth, &fHeight, &iFirstFrame, &nPlanes, &fBufSize);
fWidthOffs = fWidth%4;
tempBuff = new BYTE[fWidth*fHeight*nPlanes];
ZeroMemory(tempBuff, sizeof(BYTE)*fWidth*fHeight*nPlanes);pFrame = AVIStreamGetFrameOpen(pStream, NULL);
bytBuff = new BYTE[fBufSize];//fWidth*fHeight*nPlanes];
// read video stream to video buffer
for (i = 0; i < frames; i ++)
{
// the returned is a packed DIB frame
imgTemp = (BYTE*) AVIStreamGetFrame(pFrame, i);RtlMoveMemory(&bih.biSize, imgTemp, sizeof(BITMAPINFOHEADER)); //now get the bitmap bits and get rid of the header information and retrieve the real image RtlMoveMemory(bytBuff, imgTemp+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)\*256, bih.biSizeImage); ind = i\*fWidth\*fHeight\*nPlanes; for (j = 0; j < fHeight; j ++) { idxd1 = j\*nStimVideoNX; idxs = (fHeight-1-j) \* (fWidth \* nPlanes + fWidthOffs); for (k = 0; k < fWidth/\*nStimVideoNX\*/; k ++) { datain = bytBuff\[idxs + k\*nPlanes\]; tempBuff\[idxd1+k\] = datain; } }
}
After doing this, I am writing tempBuff to a text file to view the contents in maltab and imshow it. If you play the video, you will see two black squares inside the frame, but when I check the text file for frame 3, I only see one black square. Here is the link[^] for a sample file that I am trying to read.
PKNT
-
As the title states, I am having problems reading uncompressed avi files in MFC. It works fine on some files and reads different data on some avi files. Here is the code-
pStream = g_GetAviStream(_T("D:\\Lab_Programs\\Matlab\\output.avi"), &frames, &fWidth, &fHeight, &iFirstFrame, &nPlanes, &fBufSize);
fWidthOffs = fWidth%4;
tempBuff = new BYTE[fWidth*fHeight*nPlanes];
ZeroMemory(tempBuff, sizeof(BYTE)*fWidth*fHeight*nPlanes);pFrame = AVIStreamGetFrameOpen(pStream, NULL);
bytBuff = new BYTE[fBufSize];//fWidth*fHeight*nPlanes];
// read video stream to video buffer
for (i = 0; i < frames; i ++)
{
// the returned is a packed DIB frame
imgTemp = (BYTE*) AVIStreamGetFrame(pFrame, i);RtlMoveMemory(&bih.biSize, imgTemp, sizeof(BITMAPINFOHEADER)); //now get the bitmap bits and get rid of the header information and retrieve the real image RtlMoveMemory(bytBuff, imgTemp+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)\*256, bih.biSizeImage); ind = i\*fWidth\*fHeight\*nPlanes; for (j = 0; j < fHeight; j ++) { idxd1 = j\*nStimVideoNX; idxs = (fHeight-1-j) \* (fWidth \* nPlanes + fWidthOffs); for (k = 0; k < fWidth/\*nStimVideoNX\*/; k ++) { datain = bytBuff\[idxs + k\*nPlanes\]; tempBuff\[idxd1+k\] = datain; } }
}
After doing this, I am writing tempBuff to a text file to view the contents in maltab and imshow it. If you play the video, you will see two black squares inside the frame, but when I check the text file for frame 3, I only see one black square. Here is the link[^] for a sample file that I am trying to read.
PKNT
Are you certain that all of your test files have a 256-colour palette? See the BITMAPINFOHEADER structure[^] for details about other possibilities. Note also that the height, width, and number of planes are encoded in the header. Ensure that these are as expected before decoding! Lastly, the BITMAPINFOHEADER contains its size in the first element. Use this either as a "sanity check" or instead of sizeof(BITMAPINFOHEADER).
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill
-
Are you certain that all of your test files have a 256-colour palette? See the BITMAPINFOHEADER structure[^] for details about other possibilities. Note also that the height, width, and number of planes are encoded in the header. Ensure that these are as expected before decoding! Lastly, the BITMAPINFOHEADER contains its size in the first element. Use this either as a "sanity check" or instead of sizeof(BITMAPINFOHEADER).
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill
For the file I attached in my first post, AVIFileInfo is returning the following data-
avi_info {dwMaxBytesPerSec=0 dwFlags=0 dwCaps=3 ...} _AVIFILEINFOA
dwMaxBytesPerSec 0 unsigned long
dwFlags 0 unsigned long
dwCaps 3 unsigned long
dwStreams 1 unsigned long
dwSuggestedBufferSize 2296 unsigned long
dwWidth 26 unsigned long
dwHeight 82 unsigned long
dwScale 33333 unsigned long
dwRate 1000000 unsigned long
dwLength 30 unsigned long
dwEditCount 0 unsigned long
szFileType 0x0068e930 "AVI Default File Handler" char [64]When I write the frame to a text file after
imgTemp = (BYTE*) AVIStreamGetFrame(pFrame, i);
I see the correct header of 1064 bytes, but the image data doesn't have two black squares that I am supposed to see (for example from frame 3), but only one black square. Any ideas?
PKNT
-
For the file I attached in my first post, AVIFileInfo is returning the following data-
avi_info {dwMaxBytesPerSec=0 dwFlags=0 dwCaps=3 ...} _AVIFILEINFOA
dwMaxBytesPerSec 0 unsigned long
dwFlags 0 unsigned long
dwCaps 3 unsigned long
dwStreams 1 unsigned long
dwSuggestedBufferSize 2296 unsigned long
dwWidth 26 unsigned long
dwHeight 82 unsigned long
dwScale 33333 unsigned long
dwRate 1000000 unsigned long
dwLength 30 unsigned long
dwEditCount 0 unsigned long
szFileType 0x0068e930 "AVI Default File Handler" char [64]When I write the frame to a text file after
imgTemp = (BYTE*) AVIStreamGetFrame(pFrame, i);
I see the correct header of 1064 bytes, but the image data doesn't have two black squares that I am supposed to see (for example from frame 3), but only one black square. Any ideas?
PKNT
If you are writing the data to a text file in Windows, it is quite possible that you will see garbage. You must write the file as a binary file (e.g. fopen(file, "wb")). I can't actually read your sample file (I don't have access to your OneDrive account), so I can't verify this myself.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill
-
If you are writing the data to a text file in Windows, it is quite possible that you will see garbage. You must write the file as a binary file (e.g. fopen(file, "wb")). I can't actually read your sample file (I don't have access to your OneDrive account), so I can't verify this myself.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack. --Winston Churchill
I guess I found the problem. It was the way Matlab is writing the avi files. By default, for uncompressed gray scale avi files it uses 64 level color map and indicies data to it. Now the problem is resolved.
PKNT