Introduction
When I was working with monochrome AVI files in my C++ project, I noticed that for certain machines, I needed adminitrator privilegies to install codec drivers.
As I was working in my school computer lab where those privilegies are very hard to get, I chose the way of working around the matter by using the DLL driver immediately, instead of using it via the operating system.
Background
This article uses the code of the lossless Win32 video codec Huffyuv developed by Ben Rudiak-Gould under GPL licence.
It also uses the Open Source Computer Vision Library OPENCV for viewing the frames.
Using the code
The AVI reader is wrapped in a class called CMonochromeAviReader
.
The reader uses the codec library compiled from the original Huffyuv code. The modification made to Ben's code is the key word __declspec(dllexport)
added to the codec main struct CodeInst
.
struct __declspec(dllexport) CodecInst {
...
};
Two instances were created: the first CodecInst m_codec
is for the codec, and the other one <A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_icdecompress_str.asp" target="_ blank">ICDECOMPRESS<A> m_icinfo
has to hold the tracks of both the compressed and uncompressed data for a frame.
typedef struct {
DWORD dwFlags;
LPBITMAPINFOHEADER lpbiInput;
LPVOID lpInput;
LPBITMAPINFOHEADER lpbiOutput;
LPVOID lpOutput;
DWORD ckid;
} ICDECOMPRESS;
The field lpInput
is used to extract the data from uncompressed data while lpOutput
is used for the compressed one.
IplImage* CMonochromeAviReader::ReadFrame(unsigned int index)
{
AVIStreamRead(m_pAviStream, index, 1, m_icinfo.lpInput,
m_frameStreamLength, NULL, NULL);
if(... compressed data ...)
{
m_codec.Decompress(&m_icinfo, 0);
m_codec.DecompressEnd();
cvSetImageData(m_pFrameRGB,m_icinfo.lpOutput,m_width*3);
...
return m_pFrame;
}
else if(... uncompressed data ...)
{
cvSetImageData(m_pFrame,m_icinfo.lpInput,m_width*1);
return m_pFrame;
}
else
{
return NULL;
}
}
Note that the OPENCV function cvSetImageData( IplImage* image, void* data, width)
can also be replaced by memcpy(IplImage* image->imageData,void *data, width*height)
, but cvSetImageData
is better because it is optimized to run on Intel processors and it doesn't copy all the data; it's a matter of pointing while memcopy
has to copy the memory in the newly allocated space.
Revision History
16-05-2006
- Bug in the
Close
method fixed.
15-05-2006
That's all folks!