Showing results for 
Search instead for 
Did you mean: 

Fast initialization of MPEGTS ThreadedDemuxer and reducing playback latency

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.
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_bAutoEnable = true;
{ // 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)

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:
if (m_pFC[m_iCurTrack]->GetInfo()->m_iFirstFrameOrder < 0)
m_pFC[m_iCurTrack]->GetInfo()->m_iFirstFrameOrder = m_uiTracksReady;
m_uiTracksReady += 1;

m_pOnNewTrackCallbackFunc(m_pOnNewTrackCallbackObj, m_pFC[m_iCurTrack]->GetInfo(),
0 Kudos
0 Replies