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

Using UMC decoders

vucetica
Beginner
308 Views
I'm trying to decode video stream but I do not have success in doing that. I'm working according to this example:http://software.intel.com/en-us/articles/getting-started-with-intel-ipp-unified-media-classes-sample/, but with one big difference. I do not have a full buffer of input stream but it arrives in chunks. Here is the algorithm:

[bash]bool MyDecoder::read(Buffer &buffer, unsigned int length)
{
	semaphore.lock();
	
	// Append new arrived data to currentBuffer
	currentBuffer->write(buffer, length);
	semaphore.unlock();

	return true;
}

bool MyDecoder::decode(Image ℑ)
{
	semaphore.lock();

	// We have bufferLength unread bytes to the end of buffer
	int bufferLength = currentBuffer->getUnreadLength();
	
	// 
	if(bufferLength > 1000000)
	{
		UMC::VideoData  DataOut;
		UMC::MediaData  DataIn; 
	
		...
		
		// Read all bytes into DataIn (I hope that DataIn will know how many bytes are actually used, after I call GetFrame)
		UMC_CHK(DataIn.SetBufferPointer(currentBuffer->getPointer(), bufferLength));
		UMC_CHK(DataIn.SetDataSize(bufferLength));
		
		// ... Initialize DataOut

		// Call decode. Decoder is initialized earlier (and it is not instantiated in this method, but somewhere in MyDecoder constructor, 
		// for example. It is initialized in a proper way, since I have get it working for some videos.
		UMC::Status status = decoder.GetFrame(&DataIn, &DataOut);
		
		// If we do not have decoded image, "read" will be called again
		if(status != UMC::UMC_OK) return false;
		
		...
		
		// Move read position of the buffer to the actual bytes that decoder has used in this decoding cycle
		currentBuffer->seek(DataIn.GetDataSize());
		
		// Return true, so decode will be called again
		return true;
	}
	else
	{
		// "read" will be called again until we fill buffer with at least 1000000 
		return false;
	}
	
	semaphore.unlock();
}[/bash]


What am I doing wrong? Many thanks!
Regards,
Aleksandar
0 Kudos
1 Reply
Ying_H_Intel
Employee
308 Views

Hello Aleksander,

There are some discussion about the stream data decoder in the forum.Most ofproblems should be in the decoder loops and the Datain Buffer.some ofsmall problem may be the Data in/ ut initialization.I can't check your code further as norunable test case. Could you check currentBuffer-gt;seek(DataIn.GetDataSize()); and intbufferLength=currentBuffer-gt;getUnreadLength(); make sure if the dataIn is right.


In addition, I noticed, you create a new Datainif(bufferLengthgt;1000000)ineach call, is it possible to create it in high level as it may keep some buffer data during decoding. and how do you handleUMC_ERR_NOT_ENOUGH_DATA andNULL as input? Justa quick thoughts,
the main.cpp in UMC sample should be like a chunk data reader model as it use splitter to get Datain ( a piece of chunk data) ( or you may replace the splitter->GetNextData() with your read the buffer and see if the whole decode work?)

The loop is like

for (Ipp32s i = 0; ; i++)
{
if ((3 > in->GetDataSize()) &&
(false == bEndOfStream))
{
Status statusHelper = splitter->GetNextData(in.get(), 0);
if(UMC_OK != statusHelper){
bEndOfStream = true;
}
}

if(!bInitialize)
{
.....
out->SetAlignment(16);
out->Init(params.info.clip_info.width, params.info.clip_info.height, cmd.m_cf);
out->Alloc();
continue;
}

vm_tick t_start = GET_TICKS;
Status ret = h264Decoder->GetFrame((bEndOfStream) ? (NULL) : (in.get()), out.get());
vm_tick t_end = GET_TICKS;
encode_time += (Ipp64f)(Ipp64s)(t_end-t_start);

if (UMC_ERR_NOT_ENOUGH_DATA == ret)
{
if (bEndOfStream)
break;
else
continue;
}

if (UMC_OK != ret)
continue;

// it is actually UMC_OK=OK
savedata(f_dst, out.get());
numDecodedFrames++;
if (numDecodedFrames >= cmd.m_num_frames && cmd.m_num_frames != 0)
break;
}

Regards,
Ying

0 Kudos
Reply