Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
Announcements
FPGA community forums and blogs have moved to the Altera Community. Existing Intel Community members can sign in with their current credentials.

UMC how to extract frames from MPEG2 video

ajambox-webpages
Beginner
770 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
770 Views
What version of IPP and media sample do you use?
0 Kudos
ajambox-webpages
Beginner
770 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
770 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
770 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