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

mpeg2 decoder - Input buffer question

moshe1
Beginner
418 Views

Hi, I want to reopen an issue regarding buffer handling for DataIn object in the GetFrame function.

This is the old thread about it (http://software.intel.com/en-us/forums//topic/51651) unfortunately, there was no working solution for it.

The main problem: How do I handle the input buffers. I see that decoder needs at least 1 frame, and that's fine. But when I try to call the 2nd time with less than a frame, I don't get a fully decoded picture.

Below is the code I am using (the sample code from the above thread). I can decode only the first BSIZE bytes from the bitstream. No more...

Any ideas?

Thanks,

Moshe

#define vidW 480
#define vidH 576
#define BSIZE 150000
#define MIN_SIZE 10000
UMC::VideoDecoderParams VDecParams;
UMC::MediaData dataIn;
UMC::VideoData dataOut;
UMC::Status umcRes = UMC::UMC_OK;
FILE* fp=fopen("input.m2v","rb");
unsigned char * memBuf=(unsigned char*)malloc(5*1024*1024);
int br; //Read file to memory
br = fread(memBuf,5000000,1,fp);

dataIn.SetBufferPointer(memBuf,BSIZE);
dataIn.SetDataSize(BSIZE);
MPEG2VideoDecoder* mpg2d=new UMC::MPEG2VideoDecoder();
VDecParams.m_pData = &dataIn;
VDecParams.lFlags = 0;//UMC::FLAG_VDEC_REORDER;
umcRes = mpg2d->Init(&VDecParams);
UMC::VideoDecoderParams vParams;
umcRes = mpg2d->GetInfo(&vParams);

umcRes = dataOut.Init(vParams.info.clip_info.width,
vParams.info.clip_info.height,
YUV420,
8);
dataOut.Alloc();
int cc=0;
while (cc<150)
{
umcRes = mpg2d->GetFrame(&dataIn, &dataOut);
if (umcRes!=UMC::UMC_OK && umcRes!=UMC::UMC_ERR_NOT_ENOUGH_DATA)
break;
if (umcRes==0)
{
&nbs p; static int ctr = 0;
printf("got frame: %d ",ctr);
char fname[256];
sprintf(fname,"out%04d.yuv",ctr++);
FILE* fp_out = fopen(fname,"wb");
if(! fp_out)
{
printf("Can't open file: %s ",fname);
return;
}
Ipp8u* y = (Ipp8u*)dataOut.GetPlanePointer(0);
Ipp8u* u = (Ipp8u*)dataOut.GetPlanePointer(1);
Ipp8u* v = (Ipp8u*)dataOut.GetPlanePointer(2);
if(y&&u&&v)
{
fwrite(y,1,vParams.info.clip_info.width*vParams.info.clip_info.height,fp_out);
fwrite(u,1,vParams.info.clip_info.width/2*vParams.info.clip_info.height/2,fp_out);
fwrite(v,1,vParams.info.clip_info.width/2*vParams.info.clip_info.height/2,fp_out);
}
fclose(fp_out);
}
cc++; //set to next data in buffer, just for testing
int datasize = dataIn.GetDataSize();
if(datasize {
Ipp8u* dataptr = (Ipp8u*)dataIn.GetDataPointer();
ippsCopy_8u(dataptr, memBuf, datasize); // copy tail to the head of buffer
br=fread(memBuf+datasize, BUF_SIZE-datasize, 1, fp); // read to remained space
if(br==0 && datasize < 16) break; // need more accurate EOF detection
dataIn.MoveDataPointer(memBuf - dataptr); // back to the start of the buffer
dataIn.SetDataSize(datasize + br); // remained + new read
}
&n bsp; } // end of while
free(pOut);
mpg2d->Close();
delete mpg2d;
free(memBuf);

0 Kudos
3 Replies
Leonid_K_Intel
Employee
418 Views

Chgange first file-reading line from

br = fread(memBuf,5000000,1,fp);

to

br = fread(memBuf, BUF_SIZE,1,fp);

0 Kudos
moshe1
Beginner
418 Views

Hi,

Thanks, ofcourse you were rightbut still, I amfacing the same problem.

Does this code run for you?

Moshe

0 Kudos
Leonid_K_Intel
Employee
418 Views

1. Make BSIZE and MIN_SIZE bigger. MIN_SIZE in your code in fact is maximum size of the encoded frame which can be in the stream.

2. While you don't guarantee that complete encoded frame is provided to decoder it makes sense to add 3-4 zero bytes in the end of the valid data. This will stop VLC decoding from out of the buffer.

If decoder decoded only part of the frame it returns UMC_OK.You can'tknow easily if it was complete frame. But you can check if next bytes are start codes higher than slice level.

Anyway, most safe and correct way is to scan for the next picture level start code.

0 Kudos
Reply