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

MPEG4 decoding

goldfita
Beginner
637 Views

I am using this example but need some help.

http://software.intel.com/en-us/forums//topic/51651

Please forgive the messiness. It's a work in progress.

#define vidW 640

#define vidH 480

#define BUF_SIZE 640*480*2*3

#define MIN_SIZE 100000

UMC::VideoDecoderParams VDecParams;

UMC::ColorConversionInfo ColorInit;

UMC::MediaData dataIn;

UMC::VideoData dataOut;

UMC::ColorSpaceConverter rColorConverter;

UMC::Status umcRes = UMC::UMC_OK;

unsigned char *start = pData;

dataIn.SetBufferPointer(pData,dataLength);

dataIn.SetDataSize(dataLength);

MPEG4VideoDecoder *mpg4 =

new UMC::MPEG4VideoDecoder();

VDecParams.m_pData = &dataIn;

ColorInit.FormatSource = UMC::YV12;

ColorInit.SizeSource.width = vidW;

ColorInit.SizeSource.height = vidH;

ColorInit.SizeDest.width = vidW;

ColorInit.SizeDest.height = vidH;

ColorInit.lFlags = 1;

ColorInit.lDeinterlace = 0;

ColorInit.lInterpolation = 1;

ColorInit.FormatDest = UMC::RGB24;

VDecParams.cformat = UMC::YV12;

VDecParams.lFlags = UMC::FLAG_VDEC_COMPATIBLE | UMC::FLAG_VDEC_NO_PREVIEW | UMC::FLAG_VDEC_REORDER;

TimedColorConverter *tcc =

new TimedColorConverter; //needs to be deleted...

tcc->Init(ColorInit);

VDecParams.lpConverter = tcc;

VDecParams.lpConvertInit = &ColorInit;

VDecParams.uiLimitThreads = 0;

umcRes = mpg4->Init(&VDecParams);

UMC::VideoDecoderParams vParams;

umcRes = mpg4->GetInfo(&vParams);

VDecParams.lpConvertInit->SizeSource.width=vParams.info.clip_info.width;

VDecParams.lpConvertInit->SizeSource.height=vParams.info.clip_info.height;

VDecParams.lpConvertInit->SizeDest.width=vParams.info.clip_info.width;

VDecParams.lpConvertInit->SizeDest.height=vParams.info.clip_info.height;

dataOut.SetVideoParameters(vidW, vidH, UMC::RGB24);

BYTE * pOut = (BYTE*)malloc(vidW*3*vidH);

dataOut.SetDest(pOut,pOut+480*640,pOut+480*640*2);

dataOut.SetPitch(vidW*3,vidW,vidW);

int cc=0;

while (cc<150) {

int datasize = dataIn.GetDataSize();

/*if(datasize

Ipp8u* dataptr = (Ipp8u *)dataIn.GetDataPointer();

pData = start + (dataptr - dataIn.GetBufferPointer());

ippsCopy_8u(dataptr, pData, datasize); // copy tail to the head of buffer

//ReadFile(fh,memBuf+datasize, BUF _SIZE-datasize, &br, NULL); // read to remained space

//if(br==0 && datasize < 16) break; // need more accurate EOF detection

dataIn.MoveDataPointer((Ipp8u *)dataIn.GetBufferPointer() - dataptr); // back to the start of the buffer

dataIn.SetDataSize(datasize + 0); // remained + new read

}*/

umcRes = mpg4->GetFrame(&dataIn, &dataOut);

if (umcRes!=UMC::UMC_OK && umcRes!=UMC::UMC_NOT_ENOUGH_DATA) break;

cc++;

//set to next data in buffer, just for testing

vm_byte * tbuf=(vm_byte *)dataIn.GetDataPointer();

dataIn.SetBufferPointer(tbuf,BUF_SIZE);

}

free(pOut);

mpg4->Close();

delete mpg4;

My first problem is inside the color converter. Even though I specified YV12 to RGB24, for some reason, the color converter chooses YUV to YUV conversion. The code looks correct to me, but I stepped through it (except for the macro), and it selects the wrong function. I had to add this line under 'case YV12' to fix the problem.

lpFunc = &ColorSpaceConverter::ConvertFrom_YV12_To_RGB24;

The next issue is that setDest assigns three pointers as if the BGR image planes will all be in separate locations. However, the result is returned in one image plane with BGR triples. I guess it's not really a problem, but it seems awkward given the setDest function (am I using the right function?).

Next, the MPEG4 init routine seems to decode the first I-frame. But how do I access the decoded image? The first call to getFrame returns the the second I-frame, completely skipping the whole previous GVOP.

I have this set up so that the entire MPEG is stored in pData. I would like to change it so I can pass a little data in the buffer, and when the decoder returns 'not enough data', I can pass a new buffer with the remaining data. This was done with ReadFile in the previous example. I have some code commented where I'm trying to understand what the functions do. I am also wondering if setBufferPointer is necessary in the loop.

thank you

0 Kudos
3 Replies
Vladimir_Dudnik
Employee
637 Views

Do you use our the last version of media sample, which comes with IPP 5.2 beta?

Vladimir

0 Kudos
goldfita
Beginner
637 Views

Package ID: w_ipp-sample-media_p_5.1.007
Package Contents: Intel IPP Media Processing Samples for Windows*

I have almost figured out what I'm doing. It looks like after the MPEG4 init call, I need to call MoveDataPointer before decoding the first frame. If there is not enough data in the buffer to decode a full frame, will I need to call MoveDataPointer before trying again? I.e.

//dataptr == bufferptr

getFrame() //fails (returns what?)

dataptr = GetDataPointer()

//copy more data to buffer

MoveDataPointer(GetBufferPointer() - dataptr)

getFrame() //success?

//copy end back to start

I'm still wondering why the color converter chooses the wrong routine.

------------

There is another issue. It seems if there is not enough data, at least the first time, to decode a frame, getFrame return UMC_OK. How do I know if the output image is valid?

0 Kudos
Vladimir_Dudnik
Employee
637 Views

It seems you met issue which was fixed in IPP 5.2 beta. Could you try our the latest sample?

Vladimir

0 Kudos
Reply