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

UMC how to extract frames from MPEG2 video

ajambox-webpages
Beginner
920 Views

Hello, what I would like to do is extract frames from an MPEG2 video, eventually for use with OpenCV (, etc.) but right now I'm just writing to a PPM file. When I view the PPM file, however, the image is wrong (i.e., http://www.cs.ucf.edu/~aaved/imgoutput.jpg).

My questions: How do you extract the image from the VideoData object (i.e., m_lpDest[...]). It seems the data is YUV420, however, the results from ippiYUV420ToRGB_8u_P3C3R are not correct; is this the correct function I should call? What is the 'srcStep' of the data in the VideoData.m_lpDest? (That is, the distance between starts of consecutive lines in the source image.)The image width?

Also, what is the best way to advance the data in the VideoData buffer? Can I assume if I advance it the entire buffer length, that the buffer will contain only one frame (i.e., not 1.5 frames worth of data, etc.)

Any comments would be much appreciated; I'm about out of ideas :) I've tried to keep this short, please let me know if I need to clarify something.

Thank you!

PS, my save_ppm function correctly saves the results of an ippiImageJaehne_8u_C3R function call, so I don't think its the problem.

My code:

// #includes, etc.

static void save_ppm (int width, int height, Ipp8u * buf, int num, int stepSize)
{
char filename[100];
FILE * ppmfile;

sprintf (filename, "%d.ppm", num);
ppmfile = fopen (filename, "wb");
if (!ppmfile) {
fprintf (stderr, "Could not open file "%s". ", filename);
exit (1);
}
// P6 binary, and P3 ascii
fprintf (ppmfile, "P6 %d %d 255 ", width, height);

for (int i=0; i fwrite (&buf[i*stepSize], 3 * width, 1, ppmfile);
} // save_ppm

int _tmain(int argc, _TCHAR* argv[])
{

ippStaticInit();

char* fname;
vm_char* szFileName;

fname = "c:\temp\SR436_M2U00037.MPG";
szFileName = VM_STRING(fname);

UMC::FIOReader fr;
UMC::FileReaderParams frp;
UMC::Status umc_status;
UMC::MpegSplitterParams splParams;
UMC::SplitterInfospi;
UMC::MPEG2Splitter mpgSplitter;

UMC::ColorSpaceConverter cc;
UMC::ColorConversionInfo cci;

UMC::MediaDataEx md;
UMC::MPEG2VideoDecoder vd;
UMC::VideoDecoderParams vdp;

vm_string_strcpy(frp.m_file_name, szFileName);
frp.m_portion_size = 0;

umc_status = fr.Init(&frp);

splParams.m_pDataReader = &fr;
splParams.m_lFlags = UMC::VIDEO_SPLITTER | UMC::FLAG_VSPL_VIDEO_FRAME_REQ;

splParams.m_mediaData = &md;

if ((umc_status = mpgSplitter.Init(splParams)) != UMC::UMC_OK) {
printf(" Error mpgSplitter.Init(): %d", umc_status);
exit(1);
}
else
printf(" Init'd splitter");

if (mpgSplitter.GetInfo(&spi) != UMC::UMC_OK) {
printf(" Error mpgSplitter.GetInfo()");
exit(1);
}
else
printf (" called splitter.GetInfo()");

cci.FormatDest = UMC::YV12;
cci.SizeSource.width = spi.m_video_info.clip_info.width;
cci.SizeSource.height = spi.m_video_info.clip_info.height;
cci.SizeDest.height = spi.m_video_info.clip_info.width;
cci.SizeDest.width = spi.m_video_info.clip_info.height;
cci.lFlags = 1;
cci.lDeinterlace = 0;
cci.lInterpolation = UMC::FLAG_CCNV_CONVERT;

vdp.info = spi.m_video_info;
vdp.cformat = UMC::YV12;
vdp.lFlags = 0;
//vdp.lFlags = UMC::FLAG_VDEC_COMPATIBLE | UMC::FLAG_VDEC_NO_PREVIEW | UMC::FLAG_VDEC_REORDER;
vdp.lpConverter = &cc;// Pointer to color converter
vdp.lpConvertInit = &cci;// ptr to structure w/ conversion info
vdp.uiLimitThreads = 1;
vdp.m_pData = &md;// Init'd MediaData buffer


if ((umc_status = vd.Init(&vdp)) != UMC::UMC_OK) {
printf(" Error Init'ing Video Decoder");
exit(1);
}
else
printf(" Init'd video decoder");

printf(" File: %s", fname);
printf(" Type: %s", VideoStreamTypeStr(spi.m_video_info.stream_type));
printf(" Dims: %dx%d", spi.m_video_info.clip_info.width, spi.m_video_info.clip_info.height);
printf(" Color: %s", ColorFormatStr(spi.m_video_info.color_format));
printf(" Duration: %f", spi.m_video_info.duration / 60);

UMC::MJPEGVideoDecoder mjpeg_dec;
UMC::VideoData out;

out.Init(spi.m_video_info.clip_info.width, spi.m_video_info.clip_info.height, spi.m_video_info.color_format);
out.SetColorFormat(UMC::YV12);

unsigned int nframes = 0;

umc_status = UMC::UMC_OK;
UMC::MediaData in;
UMC::FWVideoRender vr; // VideoRender to display decompressed video stream
UMC::VideoRenderParams video_params;

video_params.color_format = spi.m_video_info.color_format;
video_params.info = spi.m_video_info.clip_info;

if ((umc_status = vr.Init(&video_params)) != UMC::UMC_OK)
{
printf(" Error Init'ing video renderer %d", umc_status);
exit(1);
}

printf(" ");

IppiSize roiSize = {spi.m_video_info.clip_info.width, spi.m_video_info.clip_info.height};
int height = spi.m_video_info.clip_info.height;
int width = spi.m_video_info.clip_info.width;

int stepBytes = height;
Ipp8u* pOut = ippiMalloc_8u_C3(width, height, &stepBytes);


IppStatus stus;

while (umc_status == UMC::UMC_OK || umc_status == UMC::UMC_NOT_ENOUGH_DATA)
{
umc_status = mpgSplitter.GetNextVideoData(&in);
if (umc_status != UMC::UMC_OK)
break;

umc_status = vr.LockInputBuffer(&out);
if (umc_status != UMC::UMC_OK)
break;

umc_status = vd.GetFrame(&in, &out);
if (umc_status != UMC::UMC_OK)// -998 - UMC_NOT_INITIALIZED -996 - not enough data
//break;
con tinue;


printf(" Color: %s", ColorFormatStr(out.m_ColorFormat));
// prints out "YUV420"

if (umc_status == UMC::UMC_OK)
{

const Ipp8u* pSrcYUV[3] = {out.m_lpDest[0], out.m_lpDest[2], out.m_lpDest[1]};

int step[3] = {width, width, width}; // I'm guessing its `width'

stus = ippiYUV420ToRGB_8u_P3C3R(pSrcYUV, step, pOut, stepBytes, roiSize);

save_ppm(720, 480, pOut, nframes, stepBytes);


umc_status = vr.UnLockInputBuffer(&out);
if (umc_status != UMC::UMC_OK)
break;

umc_status = vr.RenderFrame();
if (umc_status != UMC::UMC_OK)
break;
}

nframes++;

if (nframes == 10)
{
printf(" processed 10 frames...exiting... ");
exit(102);
}


} // while

ippFree(pOut);
return 0;
}

0 Kudos
4 Replies
Vladimir_Dudnik
Employee
920 Views
What version of IPP and media sample do you use?
0 Kudos
ajambox-webpages
Beginner
920 Views

Intel Integrated Performance Primitives
ippcore-5.1.dll, 5.1.1 {5.1.133.240}, build date Dec 19 2006
ippsw7-5.1.dll, 5.1.1 {5.1.133.277}, build date Dec 19 2006
ippiw7-5.1.dll, 5.1.1 {5.1.133.275}, build date Dec 19 2006
ippjw7-5.1.dll, 5.1.1 {5.1.133.250}, build date Jun 17 2006
ippccw7-5.1.dll, 5.1.1 {5.1.133.181}, build date Jun 17 2006

and 5.1 Media sample. Compiler is MS Visual C++ 2005 w/ the service pack.

0 Kudos
ajambox-webpages
Beginner
920 Views

I figured out the srcStep; it comes from m_lPitch member variable of UMC::VideoData. However, using

ippiYCbCr420ToRGB_8u_P3C3R(pSrcYUV, step, pOut, stepBytes, roiSize);

I'm still getting incorrect results: (http://www.cs.ucf.edu/~aaved/out2.jpg)

0 Kudos
Vladimir_Dudnik
Employee
920 Views

Did you try code like this one?

int step[3] = {

out.m_lPitch [0], out.m_lPitch [2], out.m_lPitch [1]}; // I'm guessing its `width'

stus = ippiYUV420ToRGB_8u_P3C3R(pSrcYUV, step, pOut, stepBytes, roiSize);

Regards,
Vladimir

0 Kudos
Reply