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