Log in

View Full Version : ICDecompress (& co) issues/work-arounds


Verge
24th April 2006, 00:31
Win32/VFW/VC++ 7.1

Greetings and salutations...

There seems to be some unworkable issues with certain codecs and the ICDecompress family of APIs.

"ICOpen()", when called with the ICMODE_DECOMPRESS flag, returns an HIC ... or handle to a compressor. What's really happening is that the corresponding library is loaded. That takes time.

If you want to decompress a single frame, you then must call ICDecompressBegin, ICDecompress, and ICDecompressEnd in succession, followed by ICClose.

Doesn't make sense to open and close the compressor for a single frame, but certain codecs seem to require it... or they hang on you... case in point is 'mrle' (msrle32.dll)

Here's the relevant code. Imagine how inefficient it is when trying to do simple stream playback... the library is loaded/unloaded after every frame!


LRESULT returnval = 0;

if(!_hic)
_hic = ::ICOpen(ICTYPE_VIDEO,_streaminfo->fccHandler,ICMODE_DECOMPRESS);

if(_hic)
{
if(ICERR_OK == (returnval = ICDecompressBegin(_hic,originalinfo,bitmapinfo)))
{
if(ICERR_OK == (returnval = ::ICDecompress(_hic,0,&originalinfo->bmiHeader, (void *)original, &bitmapinfo->bmiHeader, (void *)newframedata)))
{
if(ICERR_OK == (returnval = ICDecompressEnd(_hic)))
{
if(ICERR_OK != (returnval = (DWORD)::ICClose(_hic)))
_newframe = 0;
else _hic = 0;
}
else _newframe = 0;
}
else _newframe = 0;
}
else _newframe = 0;

if(!_newframe)
Error::set(Win32::VFW::AVILibrary::errorString(returnval),__FILE__,__LINE__);

}
else
{
// hic not opened message, and such
}


The way the architecture of this code is set up, it must be called each time a frame is needed... that's just the way everything is built.

I've tried wrapping some of the APIs in a class, callable with a static member that returns an HIC when given a corresponding
"fccHandler"... the class makes it so there's only one HIC per opened decompressor... but when integrated into the code above, the frame-retreiving thread hangs for a short time... when decompressing a test stream (16-bit RGB, decompressed with handler 'mrle')

If I leave the code alone, as above, there are no hangs or anything... just a lot of "LOADED: .... msrle32.dll" "UNLOADED: .... msrle32.dll" messages in the Output pane of VC++ 7.1 during debug.

----

Are there issues I should know about keeping an HIC handle open like I attempted to do? Each frame in the test stream was the same identical format... I shouldn't have had to repeat a call to ICDecompressBegin to change the format for each frame.

Thanks for your time... and greetings again


Chad

:thanks:

Bester
24th April 2006, 08:23
If you want to decompress a single frame, you then must call ICDecompressBegin, ICDecompress, and ICDecompressEnd in succession, followed by ICClose.

If it is only about decompressing, why don't you use :

pVideoFrame = AVIStreamGetFrameOpen(pVideoStream, (LPBITMAPINFOHEADER)AVIGETFRAMEF_BESTDISPLAYFMT);

lpBitmapInfoHeader = AVIStreamGetFrame(pVideoFrame, n);

It handles everything for you. I haven't got any problems.

Verge
24th April 2006, 17:28
IGetFrame works , but this application allows one to decompress using more than just the native codec. You run what's called a "decompression profile", which finds all codecs that can decompress a particular stream. Then you can select the fastest/highest quality/etc.

You can also decompress to several different destination formats... "16-bit YUY, 24-bit YUY"... etc...

Only the native handler for each fcctype returns an IGetFrame interface... the rest of the time, you must call the ICM APIs.

When the app switches decompression codecs, it goes from using the IGetFrame interface to ICM, and back.

Thanks for your response


Chad