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

H264VideoDecoder::Reset won't work in 7.0.1

ismaelbej
Beginner
398 Views
In version 6.1 we used H264VideoDecoder::Reset to reuse the decoder after a callingSplitter::SetTimePosition, but in the v7.0.1.041 after calling Reset the decoder will always return UMC_ERR_NOT_ENOUGH_DATA even after reading the whole file.

[cpp]#include "ipp.h"
#include "umc_file_reader.h"
#include "umc_fio_reader.h"
#include "umc_mp4_spl.h"
#include "umc_splitter.h"
#include "umc_video_render.h"
#include "fw_video_render.h"
#include "umc_h264_dec.h"
#include "vm_time.h"

void EncodeStream(vm_char * inputfilename, vm_char * outputfilename )
{
   	Ipp32u videoTrack=0; int exit_flag =0;
	UMC::Status status;  
	UMC::MediaData in; UMC::VideoData out;	
	UMC::FIOReader reader; UMC::FileReaderParams readerParams;
	UMC::SplitterParams splitterParams; UMC::SplitterInfo * streamInfo;
	UMC::MP4Splitter Splitter;
		
	UMC::VideoStreamInfo *videoInfo=NULL;
	UMC::VideoDecoder *  videoDecoder; UMC::VideoDecoderParams videoDecParams;
	UMC::FWVideoRender fwRender; UMC::FWVideoRenderParams fwRenderParams;
	
	readerParams.m_portion_size = 0;
	vm_string_strcpy(readerParams.m_file_name, inputfilename);
	if((status = reader.Init(&readerParams))!= UMC::UMC_OK) 
       return;
	splitterParams.m_lFlags = UMC::VIDEO_SPLITTER;
	splitterParams.m_pDataReader = &reader;
    if((status = Splitter.Init(splitterParams))!= UMC::UMC_OK)
	   return;
	Splitter.GetInfo(&streamInfo);
    for (videoTrack = 0; videoTrack <  streamInfo->m_nOfTracks; videoTrack++) {
      if (streamInfo->m_ppTrackInfo[videoTrack]->m_Type == UMC::TRACK_H264)
           break;
    }
	videoInfo = (UMC::VideoStreamInfo*)(streamInfo->m_ppTrackInfo[videoTrack]->m_pStreamInfo);
	if(videoInfo->stream_type!=UMC::H264_VIDEO)
        return;
    videoDecParams.info =  (*videoInfo);
	videoDecParams.m_pData = streamInfo->m_ppTrackInfo[videoTrack]->m_pDecSpecInfo;
	videoDecParams.numThreads = 1;
    videoDecoder = (UMC::VideoDecoder*)(new UMC::H264VideoDecoder());
	if((status = videoDecoder->Init(&videoDecParams))!= UMC::UMC_OK)
		return;
	fwRenderParams.out_data_template.Init(videoInfo->clip_info.width, videoInfo->clip_info.height, videoInfo->color_format);
    fwRenderParams.pOutFile = outputfilename;
    if(status = fwRender.Init(&fwRenderParams)!= UMC::UMC_OK)
		return;

	Splitter.Run();
	int flag = 0;
	do
	{   do{ 
		     if (in.GetDataSize() < 4) {
	    	     do{ 
	              status= Splitter.GetNextData(&in,videoTrack);
			       if(status==UMC::UMC_ERR_NOT_ENOUGH_DATA)
   			            vm_time_sleep(5);
			      }while(status==UMC::UMC_ERR_NOT_ENOUGH_DATA);
			      if(((status != UMC::UMC_OK) && (status != UMC::UMC_ERR_END_OF_STREAM))||
				     (status == UMC::UMC_ERR_END_OF_STREAM)&& (in.GetDataSize()<4)) {
                        exit_flag=1;
				  }
             }
			 fwRender.LockInputBuffer(&out);
		     videoDecoder->GetFrame(&in,&out);
			 if (flag == 0 && out.GetDataSize()>0) {
				 // Calling Reset after decoding a frame will result in a decoder always returning a
				 // UMC_ERR_NOT_ENOUGH_DATA
				 // but this worked in 6.1
				 flag = 1;
				 Splitter.SetTimePosition(0.f);
				 videoDecoder->Reset();
				 Splitter.Run();
				 out.SetDataSize(0);
			 }
    	  	 fwRender.UnLockInputBuffer(&out);
		     fwRender.RenderFrame();
	     }while(!exit_flag && (status == UMC::UMC_ERR_NOT_ENOUGH_DATA || status == UMC::UMC_ERR_SYNC));
	 }while (exit_flag!=1);

	 do{  
		 fwRender.LockInputBuffer(&out);
	     status  = videoDecoder->GetFrame(NULL,&out);
	     fwRender.UnLockInputBuffer(&out);
         fwRender.RenderFrame();
	}while(status == UMC::UMC_OK);			
}

void main(int argc, vm_char* argv[])
{
   vm_char *  InputVideofileName, *OutputYUVFileName;
   InputVideofileName = _T("The Simpsons Movie - Trailer.mp4"); //use unicode string if project use unicode characters
   OutputYUVFileName  = _T("testoutput.yuv"); //use unicode string if project use unicode characters

   EncodeStream(InputVideofileName,OutputYUVFileName);
}[/cpp]
0 Kudos
1 Solution
Pavel_V_Intel
Employee
398 Views
Good day.

Problem could be fixed this way:
In thefile "umc_h264_au_splitter.cpp" there is method "void AU_Splitter::Reset()" on line 100. Add parameter "true" to "m_Headers.Reset()"in order to omitinfo headers release.

[cpp]void AU_Splitter::Reset()
{
    if (m_pNALSplitter.get())
        m_pNALSplitter->Reset();

    m_Headers.Reset(true); // partial reset
}
[/cpp]

View solution in original post

0 Kudos
4 Replies
PaulF_IntelCorp
Employee
398 Views
Hello Ismael,

Thank you for that updated encoder. I will forward it to the attention of our engineering folks.

Paul
0 Kudos
oxydius
New Contributor I
398 Views
There seems to be an issue withUMC::H264VideoDecoder::Reset() in 7.0.1. I can get it to decode after calling Reset() but it decodes garbage (output slowly turns pink). I think the TaskSupplier doesn't reset its headers properly, because the debugger reveals the SPS structure contains a lot of 0xfeeefeee invalid values. See umc_h264_heap.h.
Ismael, one solution I've found is to simply reallocate the decoder to bypass its internal Reset().
Instead of doing "pDecoder->Reset();", do "delete pDecoder, pDecoder = new UMC::H264VideoDecoder;".
0 Kudos
Pavel_V_Intel
Employee
399 Views
Good day.

Problem could be fixed this way:
In thefile "umc_h264_au_splitter.cpp" there is method "void AU_Splitter::Reset()" on line 100. Add parameter "true" to "m_Headers.Reset()"in order to omitinfo headers release.

[cpp]void AU_Splitter::Reset()
{
    if (m_pNALSplitter.get())
        m_pNALSplitter->Reset();

    m_Headers.Reset(true); // partial reset
}
[/cpp]
0 Kudos
ismaelbej
Beginner
398 Views
Thank you, now it is working again.
0 Kudos
Reply