, m_bufferStartTime(-1)
, m_bufferDuration(-1)
, m_presentationClock(0)
+ , m_sampleRequested(false)
, m_currentMediaType(0)
, m_prerolling(false)
, m_prerollTargetTime(0)
schedulePresentation(true);
}
+ void clearScheduledFrame()
+ {
+ QMutexLocker locker(&m_mutex);
+ if (m_scheduledBuffer) {
+ m_scheduledBuffer->Release();
+ m_scheduledBuffer = NULL;
+ }
+ }
+
enum
{
StartSurface = QEvent::User,
{
}
- int targetTime()
+ MFTIME targetTime()
{
return m_time;
}
HRESULT processSampleData(IMFSample *pSample)
{
+ m_sampleRequested = false;
+
LONGLONG time, duration = -1;
HRESULT hr = pSample->GetSampleTime(&time);
if (SUCCEEDED(hr))
break;
}
}
- if (requestSample && m_bufferCache.size() < BUFFER_CACHE_SIZE)
+ if (requestSample && !m_sampleRequested && m_bufferCache.size() < BUFFER_CACHE_SIZE) {
+ m_sampleRequested = true;
queueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, NULL);
+ }
}
IMFMediaBuffer *m_scheduledBuffer;
MFTIME m_bufferStartTime;
MFTIME m_bufferDuration;
IMFPresentationClock *m_presentationClock;
+ bool m_sampleRequested;
float m_rate;
};
m_stream->present();
}
+ void clearScheduledFrame()
+ {
+ QMutexLocker locker(&m_mutex);
+ if (m_shutdown)
+ return;
+ m_stream->clearScheduledFrame();
+ }
+
MFTIME getTime()
{
QMutexLocker locker(&m_mutex);
m_sink->present();
}
+ void clearScheduledFrame()
+ {
+ QMutexLocker locker(&m_mutex);
+ if (!m_sink)
+ return;
+ m_sink->clearScheduledFrame();
+ }
+
MFTIME getTime()
{
if (m_sink)
MFTIME targetTime = static_cast<MediaStream::PresentEvent*>(event)->targetTime();
MFTIME currentTime = static_cast<VideoRendererActivate*>(m_currentActivate)->getTime();
float playRate = static_cast<VideoRendererActivate*>(m_currentActivate)->getPlayRate();
- if (playRate > 0.0001f && targetTime > currentTime)
- QTimer::singleShot(int((float)((targetTime - currentTime) / 10000) / playRate), this, SLOT(present()));
- else
+ if (!qFuzzyIsNull(playRate)) {
+ // If the scheduled frame is too late or too much in advance, skip it
+ const int diff = (targetTime - currentTime) / 10000;
+ if (diff < 0 || diff > 500)
+ static_cast<VideoRendererActivate*>(m_currentActivate)->clearScheduledFrame();
+ else
+ QTimer::singleShot(diff / playRate, this, SLOT(present()));
+ } else {
present();
+ }
return;
}
if (event->type() >= MediaStream::StartSurface) {