Example #1
0
void 
DurationIndex::Add(REFERENCE_TIME tStart, REFERENCE_TIME tEnd)
{
	// In general it is safer to just use the start time of each sample
	// since the stop time will be either wrong, or will just be deduced from
	// the next sample start time.
	// However, when frame re-ordering is happening, the composition time (== PTS) will 
	// not be the same as the decode time (== DTS) and we need to use both start and
	// stop time to build the CTTS table. 
	// We save the first few timestamps and then decide which mode to be in.
	if (m_nSamples < mode_decide_count)
	{
		if (m_nSamples == 0)
		{
			m_SumDurations = 0;
		}
		m_SumDurations += (tEnd - tStart);
		
		m_SampleStarts[m_nSamples] = tStart;
		m_SampleStops[m_nSamples] = tEnd;
		m_nSamples++;
		return;
	}
	else if (m_nSamples == mode_decide_count)
	{
		// this decides on a mode and then processes 
		// all the samples in the table
		ModeDecide();
	}

	if (m_bCTTS)
	{
		AppendCTTSMode(tStart, tEnd);
	}
	else
	{
        AddDuration(long(ToScale(tStart) - m_TotalDuration));
    }
	m_nSamples++;
    m_tStartLast = tStart;
    m_tStopLast = tEnd;
    return;
}
HRESULT 
DurationIndex::WriteTable(Atom* patm)
{
    // do nothing if no samples at all
    HRESULT hr = S_OK;
	if (m_nSamples <= mode_decide_count)
	{
		ModeDecide();
	}
	if (m_nSamples > 0)
    {
		if (!m_bCTTS)
		{
			// the final sample duration has not been recorded -- use the
			// stop time
			if (ToScale(m_tStopLast) > m_TotalDuration)
			{
				AddDuration(long(ToScale(m_tStopLast) - m_TotalDuration));
			} else
				// NOTE: We still need some duration recorded, to avoid stts/stsz discrepancy at the very least
				AddDuration(1);
		}

        // create atom and write table
        smart_ptr<Atom> pstts = patm->CreateAtom('stts');
		m_STTS.Write(pstts);
        pstts->Close();

		if (m_bCTTS)
		{
			// write CTTS table
			smart_ptr<Atom> pctts = patm->CreateAtom('ctts');
			m_CTTS.Write(pctts);
			pctts->Close();
		}
    }
    return hr;
}