WMF: more reliable video seeking.

When seeking, the presentation clock can enter an undefined state until
it is started again from the new position. Wait for the clock to be
restarted before scheduling the prerolled frames, otherwise these
frames might get a wrong presentation time.

Change-Id: I02cb3338239775b7ef5d206ec5aa1b26719ac978
Reviewed-by: Christian Stromme <christian.stromme@digia.com>
This commit is contained in:
Yoann Lopes
2014-04-04 15:09:03 +02:00
committed by The Qt Project
parent 6fb0d97838
commit 0821606260

View File

@@ -655,11 +655,6 @@ namespace
m_presentationClock = NULL;
}
if (m_scheduledBuffer) {
m_scheduledBuffer->Release();
m_scheduledBuffer = NULL;
}
clearMediaTypes();
clearSampleQueue();
clearBufferCache();
@@ -677,6 +672,7 @@ namespace
QMutexLocker locker(&m_mutex);
HRESULT hr = validateOperation(OpPreroll);
if (SUCCEEDED(hr)) {
m_state = State_Prerolling;
m_prerollTargetTime = hnsUpcomingStartTime;
hr = queueAsyncOperation(OpPreroll);
}
@@ -864,6 +860,7 @@ namespace
if (m_scheduledBuffer) {
m_scheduledBuffer->Release();
m_scheduledBuffer = NULL;
schedulePresentation(true);
}
}
@@ -936,6 +933,7 @@ namespace
{
State_TypeNotSet = 0, // No media type is set
State_Ready, // Media type is set, Start has never been called.
State_Prerolling,
State_Started,
State_Paused,
State_Stopped,
@@ -1124,6 +1122,9 @@ namespace
break;
}
}
if (m_state == State_Started)
schedulePresentation(true);
case OpRestart:
endPreroll(S_FALSE);
if (SUCCEEDED(hr)) {
@@ -1142,10 +1143,7 @@ namespace
case OpStop:
// Drop samples from queue.
hr = processSamplesFromQueue(DropSamples);
if (m_scheduledBuffer) {
m_scheduledBuffer->Release();
m_scheduledBuffer = NULL;
}
clearBufferCache();
// Send the event even if the previous call failed.
hr = queueEvent(MEStreamSinkStopped, GUID_NULL, hr, NULL);
if (m_surface->isActive()) {
@@ -1388,11 +1386,16 @@ namespace
foreach (SampleBuffer sb, m_bufferCache)
sb.m_buffer->Release();
m_bufferCache.clear();
if (m_scheduledBuffer) {
m_scheduledBuffer->Release();
m_scheduledBuffer = NULL;
}
}
void schedulePresentation(bool requestSample)
{
if (m_state == State_Paused)
if (m_state == State_Paused || m_state == State_Prerolling)
return;
if (!m_scheduledBuffer) {
//get time from presentation time
@@ -1441,6 +1444,8 @@ namespace
/* Ready */ TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE,
/* Prerolling */ TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
/* Start */ FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
/* Pause */ FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,