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

Fast initialization of MPEGTS ThreadedDemuxer and reducing playback latency

pushkar_p
Beginner
211 Views
I use the IPP Threaded demuxer to read MPEGTS streams over the network. For this I subclassed the DataReader class. When I used this I found the demuxer had a large latency on initialization for network streams (e.g. 5-10 secs).
This post is to describe the changes I have done to the IPP code to solve this. I would appreciate any feedback, especially from the developers.
I have posted the relevant code changes only but I would be glad to submit the complete sources if anyone wants.
Problem:
The init method would block until the CheckNextData would return not enough buffer (UMC_ERR_NOT_ENOUGH_BUFFER) and then exit the initialization loop and signal init event.

First approach:
I modified the initialization loop in ThreadRoutine to finish as soon as the tracks that I had asked for in the rules were found:
// initialization
while (!m_bStop && !(m_uiFlags & FLAG_VSPL_FAST_INIT))
{
umcRes = m_pDemuxer->CheckNextData(&data, &uiTrack);
if (UMC_OK == umcRes)
{ // next access unit is received, check if it's from new track
if (!m_pRulesState->m_bIsTriedByRules[uiTrack])
{
if (TryTrackByRules(uiTrack))
{ // match some rule, leave it enabled
m_OnAutoEnable.Lock();
m_bAutoEnable = true;
m_OnAutoEnable.Unlock();
}
else
{ // not match to any rule, disable it
m_pDemuxer->EnableTrack(uiTrack, 0);
}
}
+++ if (m_pRulesState->m_iMatchedTracks >= m_pRulesState->m_iMaxTracks)
+++ break;
}
else if (UMC_WRN_INVALID_STREAM == umcRes)

Drawback:
This improved the situation but I found that if I asked for 1 audio and 1 video ES and if there was only a video in the stream it would still wait until the buffers were filled up before signaling the Init event.

Second approach:
So I set the FLAG_VSPL_FAST_INIT flag in the init method. Then I modified the internal demuxer to make a callback when it constructs the first frame of a new track. In the callback I pass the track info which I use to initialize the decoder. I also modified the DemuxerParams through which I set the callback function. The significant part of the modified code is in Demuxer::CheckNextDataForward:
...
m_pFC[m_iCurTrack]->GetLastFrame(data);
if (m_pFC[m_iCurTrack]->GetInfo()->m_iFirstFrameOrder < 0)
{
m_pFC[m_iCurTrack]->GetInfo()->m_iFirstFrameOrder = m_uiTracksReady;
m_uiTracksReady += 1;

if(m_pOnNewTrackCallbackFunc)
{
m_pOnNewTrackCallbackFunc(m_pOnNewTrackCallbackObj, m_pFC[m_iCurTrack]->GetInfo(),
m_iCurTrack);
}
}
....
0 Kudos
0 Replies
Reply