summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/wmf/player/mfplayersession.cpp53
-rw-r--r--src/plugins/wmf/player/mfplayersession.h1
2 files changed, 48 insertions, 6 deletions
diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp
index 69958061b..f61f7aba2 100644
--- a/src/plugins/wmf/player/mfplayersession.cpp
+++ b/src/plugins/wmf/player/mfplayersession.cpp
@@ -1157,8 +1157,8 @@ void MFPlayerSession::setPositionInternal(qint64 position, Command requestCmd)
qreal MFPlayerSession::playbackRate() const
{
- if (m_pendingState != NoPending)
- return m_request.rate;
+ if (m_scrubbing)
+ return m_restoreRate;
return m_state.rate;
}
@@ -1166,6 +1166,7 @@ void MFPlayerSession::setPlaybackRate(qreal rate)
{
if (m_scrubbing) {
m_restoreRate = rate;
+ emit playbackRateChanged(rate);
return;
}
setPlaybackRateInternal(rate);
@@ -1194,6 +1195,8 @@ void MFPlayerSession::setPlaybackRateInternal(qreal rate)
isThin = TRUE;
if (FAILED(m_rateSupport->IsRateSupported(isThin, rate, NULL))) {
qWarning() << "unable to set playbackrate = " << rate;
+ m_pendingRate = m_request.rate = m_state.rate;
+ return;
}
}
if (m_pendingState != NoPending) {
@@ -1219,6 +1222,7 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
MFTIME hnsSystemTime = 0;
MFTIME hnsClockTime = 0;
Command cmdNow = m_state.command;
+ bool resetPosition = false;
// Allowed rate transitions:
// Positive <-> negative: Stopped
// Negative <-> zero: Stopped
@@ -1229,7 +1233,12 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
Q_ASSERT(hnsSystemTime != 0);
- m_request.setCommand(rate < 0 || m_state.rate < 0 ? CmdSeekResume : CmdStart);
+ if (rate < 0 || m_state.rate < 0)
+ m_request.setCommand(CmdSeekResume);
+ else if (isThin || m_state.isThin)
+ m_request.setCommand(CmdStartAndSeek);
+ else
+ m_request.setCommand(CmdStart);
// We need to stop only when dealing with negative rates
if (rate >= 0 && m_state.rate >= 0)
@@ -1247,7 +1256,9 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
// session cannot transition back from stopped to paused.
// Therefore, this rate transition is not supported while paused.
qWarning() << "Unable to change rate from positive to negative or vice versa in paused state";
- return;
+ rate = m_state.rate;
+ isThin = m_state.isThin;
+ goto done;
}
// This happens when resuming playback after scrubbing in pause mode.
@@ -1279,17 +1290,42 @@ void MFPlayerSession::commitRateChange(qreal rate, BOOL isThin)
// Resume to the current position (stop() will reset the position to 0)
m_request.start = hnsClockTime / 10000;
+ } else if (!isThin && m_state.isThin) {
+ if (cmdNow == CmdStart) {
+ // When thinning, only key frames are read and presented. Going back
+ // to normal playback requires to reset the current position to force
+ // the pipeline to decode the actual frame at the current position
+ // (which might be earlier than the last decoded key frame)
+ resetPosition = true;
+ } else if (cmdNow == CmdPause) {
+ // If paused, dont reset the position until we resume, otherwise
+ // a new frame will be rendered
+ m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
+ m_request.setCommand(CmdSeekResume);
+ m_request.start = hnsClockTime / 10000;
+ }
+
}
// Set the rate.
if (FAILED(m_rateControl->SetRate(isThin, rate))) {
qWarning() << "failed to set playbackrate = " << rate;
- return;
+ rate = m_state.rate;
+ isThin = m_state.isThin;
+ goto done;
}
+ if (resetPosition) {
+ m_presentationClock->GetCorrelatedTime(0, &hnsClockTime, &hnsSystemTime);
+ setPosition(hnsClockTime / 10000);
+ }
+
+done:
// Adjust our current rate and requested rate.
m_pendingRate = m_request.rate = m_state.rate = rate;
-
+ if (rate != 0)
+ m_state.isThin = isThin;
+ emit playbackRateChanged(rate);
}
void MFPlayerSession::scrub(bool enableScrub)
@@ -1705,6 +1741,11 @@ void MFPlayerSession::updatePendingCommands(Command command)
case CmdSeek:
case CmdSeekResume:
setPositionInternal(m_request.start, m_request.command);
+ break;
+ case CmdStartAndSeek:
+ start();
+ setPositionInternal(m_request.start, m_request.command);
+ break;
}
m_request.setCommand(CmdNone);
}
diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h
index 3ba43ce58..2c87f3cc6 100644
--- a/src/plugins/wmf/player/mfplayersession.h
+++ b/src/plugins/wmf/player/mfplayersession.h
@@ -165,6 +165,7 @@ private:
CmdPause,
CmdSeek,
CmdSeekResume,
+ CmdStartAndSeek
};
void clear();