in FFmpegInterop/Source/MediaSampleProvider.cpp [164:237]
HRESULT FFmpegInterop::MediaSampleProvider::GetNextPacket(DataWriter ^ writer, LONGLONG & pts, LONGLONG & dur, bool allowSkip)
{
HRESULT hr = S_OK;
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.data = NULL;
avPacket.size = 0;
bool frameComplete = false;
bool decodeSuccess = true;
int64_t framePts = 0, frameDuration = 0;
int errorCount = 0;
while (SUCCEEDED(hr) && !frameComplete)
{
// Continue reading until there is an appropriate packet in the stream
while (m_packetQueue.empty())
{
if (m_pReader->ReadPacket() < 0)
{
DebugMessage(L"GetNextSample reaching EOF\n");
hr = E_FAIL;
break;
}
}
if (!m_packetQueue.empty())
{
// Pick the packets from the queue one at a time
avPacket = PopPacket();
framePts = avPacket.pts;
frameDuration = avPacket.duration;
// Decode the packet if necessary, it will update the presentation time if necessary
hr = DecodeAVPacket(writer, &avPacket, framePts, frameDuration);
frameComplete = (hr == S_OK);
if (!frameComplete)
{
m_isDiscontinuous = true;
if (allowSkip && errorCount++ < 10)
{
// skip a few broken packets (maybe make this configurable later)
DebugMessage(L"Skipping broken packet\n");
hr = S_OK;
}
}
}
}
if (SUCCEEDED(hr))
{
// Write the packet out
hr = WriteAVPacketToStream(writer, &avPacket);
if (m_startOffset == AV_NOPTS_VALUE)
{
//if we havent set m_startOffset already
DebugMessage(L"Saving m_startOffset\n");
//in some real-time streams framePts is less than 0 so we need to make sure m_startOffset is never negative
m_startOffset = framePts < 0 ? 0 : framePts;
}
pts = LONGLONG(av_q2d(m_pAvFormatCtx->streams[m_streamIndex]->time_base) * 10000000 * (framePts - m_startOffset));
dur = LONGLONG(av_q2d(m_pAvFormatCtx->streams[m_streamIndex]->time_base) * 10000000 * frameDuration);
}
av_packet_unref(&avPacket);
return hr;
}