Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

VC1Decoder Problem

Dennis_W
Beginner
339 Views
I am starting up in using the the VC1Encoder and VC1Decoder and using version 6.1.
I created a test app where I have a 24 bit RGB DIB I convert it to YUV420, encode it, decode it and convert the YUV420 to 24 bit RGB DIB.
I know the coverters are working and it appears that the encoder works, but when I try to decode, GetFrame returns UMC_ERR_NOT_ENOUGH_DATA. The buffers seem to indicate that the data is there.

I tried to follow the example in the documentation. Below is the essence of the code. Any help would be appreciated.

Thank you.

void
IntelVC1ImageFileAdapter::ConvertFromRGBToYUV(BitmapInterface::DecompressedImageFrameBitmap* imageFrame)
{

Ipp8u* pSrc = (Ipp8u*)imageFrame->bitmapBits();
IppiSize roiSize;
roiSize.width = imageFrame->width();
roiSize.height = imageFrame->height();
IppStatus stat= ippiRGBToYUV420_8u_C3P3(pSrc,
(Ipp8u**)mRGBToYUVBuffer, roiSize);



}

void
IntelVC1ImageFileAdapter::IntelVC1CompressFrame(BitmapInterface::DecompressedImageFrameBitmap* imageFrame,
void** compressedFrame, size_t& compressedFrameSize)
{

UMC::Status err = UMC::UMC_OK;
mVC1Encoder = new UMC::VC1VideoEncoder();
UMC::VC1EncoderParams *params = new UMC::VC1EncoderParams();
params->info.clip_info.width = imageFrame->width();
params->info.clip_info.height = imageFrame->height();
params->info.bitrate = 1000000;
params->info.framerate = 30.00;
params->numThreads = 1;
params->m_uiNumFrames = 1;
params->info.stream_type = UMC::VC1_VIDEO;
params->info.stream_subtype = UMC::VC1_VIDEO_VC1;
4:50 PM 9/28/2009
//params->key_frame_controls.method=1;
err = mVC1Encoder->Init(params);
delete params;

UMC::Status err;
UMC::VideoData in;
err = in.Init((Ipp32s) imageFrame->width(), (Ipp32s) imageFrame->height(),
3, 8);
err = in.SetFrameType(UMC::FrameType::VIDEO_FRAME);
size_t size = imageFrame->width()*imageFrame->height()*3/2;
err = in.SetColorFormat(UMC::ColorFormat::YUV420);

err = in.SetPlaneBitDepth(8, 0);
err = in.SetPlaneBitDepth(8, 1);
err = in.SetPlaneBitDepth(8, 2);
err = in.SetPlanePointer((Ipp8u*)mRGBToYUVBuffer[0], 0);
err = in.SetPlanePointer((Ipp8u*)mRGBToYUVBuffer[1], 1);
err = in.SetPlanePointer((Ipp8u*)mRGBToYUVBuffer[2], 2);
UMC::MediaData out;
err = out.SetFrameType(UMC::FrameType::VIDEO_FRAME);

*compressedFrame = Malloc(size);
out.SetBufferPointer((Ipp8u*)(*compressedFrame), size);

err = mVC1Encoder->GetFrame(&in, &out);
*compressedFrame = out.GetDataPointer();

compressedFrameSize = out.GetDataSize();
UMC::FileWriterParams params;
UMC::FileWriter writer;
vm_string_strcpy(params.m_file_name, "d:\\output_file.dat");
params.m_portion_size = 0;
err = writer.Init(&params);
Ipp32s iSize = out.GetDataSize();
err = writer.PutData(*compressedFrame, iSize);
err = writer.Close();
err = mVC1Encoder->Close();
delete mVC1Encoder;
}


BOOL
IntelVC1ImageFileAdapter::IntelVC1DecompressFrame(void* inputFrame, size_t sizeOfFrame,
BitmapInterface::DecompressedImageFrameBitmap* imageFrame)
{
UMC::Status umcSts;
UMC::FileReader* fileReader = new UMC::FileReader();
UMC::FileReaderParams fileParams;
UMC::SplitterParams splParams;
UMC::VideoDecoderParams params;
UMC::MediaDataEx mediaData;
UMC::VideoData yuv_data;

if(fileReader == NULL)
{
return FALSE;//UMC::UMC_ERR_FAILED;
}
fileParams.m_portion_size = 0;
vm_string_strcpy(fileParams.m_file_name, "d:\\output_file.dat");
umcSts = fileReader->Init(&fileParams);
if(umcSts != UMC::UMC_OK)
{
delete fileReader;
return FALSE;//UMC::UMC_ERR_FAILED;
}
//SPLITTER
UMC::VC1Splitter* splitter = new UMC::VC1Splitter();
if(splitter == NULL)
{
delete fileReader;
return FALSE;//UMC::UMC_ERR_FAILED;
}
splParams.m_pDataReader = fileReader;
splParams.m_lFlags = UMC::FLAG_VSPL_4BYTE_ACCESS;
umcSts = splitter->Init(splParams);
if(umcSts != UMC::UMC_OK)
{
delete fileReader;
delete splitter;
return FALSE;//UMC::UMC_ERR_FAILED;
}
UMC::SplitterInfo* splInfo = new UMC::SplitterInfo();
if(splInfo == NULL)
{
delete fileReader;
delete splitter;
return FALSE;//UMC::UMC_ERR_FAILED;
}
//DECODER
mVC1Decoder = new UMC::VC1VideoDecoder;
if(mVC1Decoder == NULL)
{
delete fileReader;
delete splitter;
return FALSE;//UMC::UMC_ERR_FAILED;
}
//return sequence header
umcSts = splitter->GetNextData(&mediaData,0);
if(umcSts != UMC::UMC_OK)
{
delete fileReader;
delete splitter;
return FALSE;//UMC::UMC_ERR_FAILED;
}
//return splitter parameters
umcSts = splitter->GetInfo(&splInfo);
params.m_pData = &mediaData;
UMC::VideoStreamInfo* videoInfo = (UMC::VideoStreamInfo*)(splInfo->m_ppTrackInfo[0]->m_pStreamInfo);
params.info.clip_info.height = videoInfo->clip_info.height;
params.info.clip_info.width = videoInfo->clip_info.width;
params.lFlags = splInfo->m_splitter_flags;
params.info.stream_type = videoInfo->stream_type;
params.info.stream_subtype = videoInfo->stream_subtype;
params.info.interlace_type = videoInfo->interlace_type;
params.info.color_format = videoInfo->color_format;
//params.info.clip_info.height = splInfo->m_video_info.clip_info.height;
//params.streamName = (Ipp8u*)argv[1];
umcSts = mVC1Decoder->Init(&params);
if(umcSts != UMC::UMC_OK)
{
delete fileReader;
delete splitter;
delete mVC1Decoder;
return FALSE;//UMC::UMC_ERR_FAILED;
}
//main cycle
UMC::Status umcSpl = UMC::UMC_OK;
int frameCount = 0;
while(umcSpl == UMC::UMC_OK)
{
//get new frame
umcSpl = splitter->GetNextData(&mediaData, 0);
if(umcSpl!= UMC::UMC_OK)
break;
//decoding}
umcSts = mVC1Decoder->GetFrame(&mediaData, &yuv_data);
switch(umcSts)
{
case UMC::UMC_ERR_NOT_ENOUGH_DATA:
umcSts = mVC1Decoder->GetFrame(&mediaData, &yuv_data);
break;
case UMC::UMC_OK:
{
frameCount++;
// yuv_data contains decoding result
break;
default:
umcSpl = umcSts;
printf("Frame decoding error\n");
break;
}
}
}
//get last frame from decoder internal buffer
//umcSts = mVC1Decoder-> GetFrame (NULL, &yuv_data);
mDecoderOutputBuffer[0] = yuv_data.GetPlanePointer(0);
mDecoderOutputBuffer[1] = yuv_data.GetPlanePointer(1);
mDecoderOutputBuffer[2] = yuv_data.GetPlanePointer(2);
mVC1Decoder->Close();
splitter->Close();
fileReader->Close();
delete fileReader;
delete splitter;
delete mVC1Decoder;
}

void
IntelVC1ImageFileAdapter::ConvertFromYUVToRGB(BitmapInterface::DecompressedImageFrameBitmap* imageFrame)
{
IppiSize roiSize;
roiSize.width = imageFrame->width();
roiSize.height = imageFrame->height();
IppStatus stat= ippiYUV420ToRGB_8u_P3C3((const Ipp8u**)mDecoderOutputBuffer,
(Ipp8u*)mYUVToRGBBuffer, roiSize);

}

buffers had been allocated earlier in the codeas

BITMAPINFO* pBitmapInfo =
imageFrame->pbitmapInfo();
size_t size = imageFrame->width()*imageFrame->height();
BYTE* arrays
mRGBToYUVBuffer[0] = Malloc(size);
mRGBToYUVBuffer[1] = Malloc(size/4);
mRGBToYUVBuffer[2] = Malloc(size/4);

mDecoderOutputBuffer[0] = Malloc(size);
mDecoderOutputBuffer[1] = Malloc(size/4);
mDecoderOutputBuffer[2] = Malloc(size/4);

BYTE*
mYUVToRGBBuffer = Malloc(size*3);

The data pointer from the compress function is passed to the decompress function.

0 Kudos
3 Replies
Ying_H_Intel
Employee
339 Views

Hello Dennis,

When does theflagUMC_ERR_NOT_ENOUGH_DATA show? at your last frame orat eachGetFrame call,thus cause the decode can't continue?
You may check ifthere are VC1 decoding error by writing the streamof encoder's output to one file, then check if it can be decode by simple_player.

In general,UMC doesn't takeUMC_ERR_NOT_ENOUGH_DATA aserror or quitconditionif GetFrame returnUMC_ERR_NOT_ENOUGH_DATA because the decoder doesn't start to decode untill the decodebuffer is full.

For example, you may always see thegetFrame returns UMC_ERR_NOT_ENOUGH_DATA at first severalcall GetFrame() in the samplehttp://software.intel.com/en-us/articles/getting-started-with-intel-ipp-unified-media-classes-sample/.

You have code
switch(umcSts)
{
case UMC::UMC_ERR_NOT_ENOUGH_DATA:
umcSts = mVC1Decoder->GetFrame(&mediaData, &yuv_data);
break;
What is the purpose?

How about if change the decoderlogic as the code inumc_h264_dec_con

for (Ipp32s i = 0; ; i++)
{
if ((3 > in->GetDataSize()) &&
(false == bEndOfStream))
{
Status statusHelper = splitter->GetNextData(in.get(), 0);
if(UMC_OK != statusHelper){
bEndOfStream = true;
}
}

...

Status ret = h264Decoder->GetFrame((bEndOfStream) ? (NULL) : (in.get()), out.get());

if (UMC_ERR_NOT_ENOUGH_DATA == ret)
{
if (bEndOfStream)
break;
else
continue;
}

if (UMC_OK != ret)
continue;

}

Regards,
Ying
0 Kudos
Dennis_W
Beginner
339 Views
Hello

In the code I sent which follows the example in the documentation, if you follow the while loop it keeps looping if GetFrame returns UMC_ERR_NOT_ENOUGH_DATA until VC1Splitter.GetNextData returns UMC_ERR_END_OF_STREAM. After that a call to GetFrame with the first parameter set to NULL still does not work.
I think the code sample you wrote does essentially the same thing.

Dennis
0 Kudos
Dennis_W
Beginner
339 Views
It looks like I solved it
the output VideoData object needed to be initialized like so

umcSts = yuv_data.Init((Ipp32s) imageFrame->width(), (Ipp32s) imageFrame->height(),
UMC::ColorFormat::YUV420, 8);
umcSts = yuv_data.Alloc();

This way the 3 planes are initialized and their buffers allocated.

Dennis

0 Kudos
Reply