Community
cancel
Showing results for 
Search instead for 
Did you mean: 
franknatoli
New Contributor I
58 Views

Problem Parsing MPEG-4 File

UMC reference manual, page 465, example 4-39, has sample source for decoding and rendering an MPEG-4 file which is exactly what I want to do. The sample source has a number of errors. It uses an AVI splitter and of course needs to use an MPEG-4 splitter. And it uses the obsolete version of the splitter GetInfo function. After correcting these problems, I can get to the point where the splitter initializes successfully (when I initially used the AVI splitter, the splitter initialization failed with UMC_ERR_SYNC), but the GetInfo data is all zero, stream_type, framerate, clip_info, etc.

Below is my code. Where have I gone wrong? Thanks for your time.

/ AtsPlaybackMpeg4Proc.cpp
//

#include "stdafx.h"
#include "AtsPlaybackMpeg4.h"

#include "AtsPlaybackMpeg4Doc.h"
#include "AtsPlaybackMpeg4View.h"

#include "ipp.h"
#include "umc_file_reader.h"
#include "umc_fio_reader.h"
#include "umc_mp4_spl.h"
#include "umc_mpeg4_video_decoder.h"
#include "umc_splitter.h"
#include "umc_video_render.h"
#include "fw_video_render.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

void CAtsPlaybackMpeg4View::PlaybackThread(void)
{
CString str;
UMC::Status umcResult;

//-------------------------------------------------------------------------
// init file reader
//-------------------------------------------------------------------------
UMC::FIOReader reader;
UMC::FileReaderParams readerParams;
readerParams.m_portion_size = 0;
vm_string_strcpy(readerParams.m_file_name, (LPCTSTR)m_strMpeg4File);
umcResult = reader.Init(&readerParams);
if (umcResult == UMC::UMC_OK)
AfxMessageBox("FIOReader.Init success");
else
{
str.Format("FIOReader.Init failure %d", umcResult);
AfxMessageBox(str);
return;
}

//-------------------------------------------------------------------------
// init splitter
//-------------------------------------------------------------------------
UMC::MP4Splitter splitter;
UMC::SplitterParams splitterParams;
splitterParams.m_lFlags = UMC::VIDEO_SPLITTER;
splitterParams.m_pDataReader = &reader;
umcResult = splitter.Init(splitterParams);
if (umcResult == UMC::UMC_OK)
AfxMessageBox("Splitter.Init success");
else
{
str.Format("Splitter.Init failure %d", umcResult);
AfxMessageBox(str);
return;
}

UMC::SplitterInfo *streamInfo;
umcResult = splitter.GetInfo(&streamInfo);
if (umcResult == UMC::UMC_OK)
AfxMessageBox("Splitter.GetInfo success");
else
{
str.Format("Splitter.GetInfo failure %d", umcResult);
AfxMessageBox(str);
return;
}

str.Format("stream_type %d framerate %d clip_info.height %d clip_info.width %d color_format %d",
streamInfo->m_video_info.stream_type,
streamInfo->m_video_info.framerate,
streamInfo->m_video_info.clip_info.height,
streamInfo->m_video_info.clip_info.width,
streamInfo->m_video_info.color_format);
AfxMessageBox(str);

if (streamInfo->m_video_info.stream_type != UMC::MPEG4_VIDEO)
{
str.Format("stream_type %d not MPEG4_VIDEO", streamInfo->m_video_info.stream_type);
AfxMessageBox(str);
return;
}

//-------------------------------------------------------------------------
// init video decoder
//-------------------------------------------------------------------------
UMC::MPEG4VideoDecoder decoder;
UMC::VideoDecoderParams decoderParams;
decoderParams.info = streamInfo->m_video_info;
decoderParams.numThreads = 1;
decoderParams.lFlags = UMC::FLAG_VDEC_REORDER;
umcResult = decoder.Init(&decoderParams);
if (umcResult == UMC::UMC_OK)
AfxMessageBox("MPEG4VideoDecoder.Init success");
else
{
str.Format("MPEG4VideoDecoder.Init failure %d", umcResult);
AfxMessageBox(str);
return;
}

//-------------------------------------------------------------------------
// init video renderer
//-------------------------------------------------------------------------
UMC::FWVideoRender render;
UMC::VideoRenderParams renderParams;
#if 0
renderParams = streamInfo->m_video_info;
#else
renderParams.color_format = streamInfo->m_video_info.color_format;
renderParams.info = streamInfo->m_video_info.clip_info;
#endif
umcResult = render.Init(&renderParams);
if (umcResult == UMC::UMC_OK)
AfxMessageBox("FWVideoRender.Init success");
else
{
str.Format("FWVideoRender.Init failure %d", umcResult);
AfxMessageBox(str);
return;
}
}

DWORD WINAPI CAtsPlaybackMpeg4View::StartPlaybackThread(LPVOID arg)
{
CAtsPlaybackMpeg4View *l pView = (CAtsPlaybackMpeg4View*)arg;
lpView->PlaybackThread();
return(0);
}

0 Kudos
4 Replies
franknatoli
New Contributor I
58 Views

Not certain, but I believe there is a bug in the new implementation of MP4Splitter::GetInfo in umc_spl_base.cpp. The new code simply reads:

Status SplitterBase::GetInfo(SplitterInfo** ppInfo)
{
ppInfo[0] = m_pInfo;
return UMC_OK;
}

The old code in umc_mp4_spl.cpp, which has one less level of indirection for the calling argument, consists of 250 lines of code, doing all kinds of analysis and computations on the MPEG-4 header data. It appears that analysis and computations is lost in the new implementation, hence my program seeing zeros for all relevant fields.

Is there a way to bring this to Intel's attention?

My temptation is to un-comment the old GetInfo code in umc_mp4_spl.cpp and call that instead.
franknatoli
New Contributor I
58 Views

The v5.3 GetInfo code in umc_mp4_spl.cpp that Intel commented out was impossible to compile when commented in, the differences between v5.2 and v5.3 being too great. Spent several hours trying to adapt the source to the changes, but gave up.

Re-installed v5.2, recompiled and relinked my program with v5.2, and now MPEG-4 splitter is working just fine, getting all the parameters correct.

So it appears someone has botched the MPEG-4 splitter in v5.3. Tried to login to https://premier.intel.com but was blocked. Sent an e-mail to Intel, no reply. Anybody home?
Vladimir_Dudnik
Employee
58 Views

Hi Frank,

I'll submit issue for you at Intel Premier Support, please expect technical support engineer will contact you.

Regards,
Vladimir

Sergey_O_Intel1
Employee
58 Views

Hello Frank!

I'm not agree about your opinion about MP4Splitter::GetInfo method. If you use it properly you'll understand its main advantages. It became more understandable, it saves your memory and supports more features.

1) Calling GetInfo you get pointer to internal MP4Splitter structure which is always up to date and is used by splitter itself. You can get all information about the stream from there. Nothing is hidden from you.

2)Now it doesn't allocate memory which is usually lost since users always forget to free it.Why shoulduser free anything if he allocated nothig? Moreover, imagine that a stream has 10 tracks and you want to get info of the 3d one. The old GetInfo would allocate memory for all 10 tracks.

3) MP4Splitter supports any number of tracks in MP4 container. That is why now wehave the only API for GetNextData where we should pass the number of track we're interested in.

So the right algorithm to work with MP4Splitter should be smth. like the following:

1. initialization - as usual

2. getting Infoptr to internal structure via MP4Splitter::GetInfo

3. Infoptr->m_nOfTracks - overall number of tracks found

then you can find Infoptr->m_ppTrackInfo - array of structures where you can find everything anout a track.

Then all youhave todo is to select the track andpass its number toGetNextData.

One trick here. If you find Infoptr->m_nDecSpecInfoLen != 0 then you should pass Infoptr->m_nDecSpecInfo to Decoder::Init so that it could be initialized in the right way.

Feel free to ask me any questions about it.

Regards

-Sergey

Reply