Bug 1309516 part 7 - modify the seek operation;r?jwwang
MozReview-Commit-ID: AZ9yK050ElM
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1446,40 +1446,35 @@ DecodingState::MaybeStartBuffering()
}
}
void
MediaDecoderStateMachine::
SeekingState::SeekCompleted()
{
int64_t seekTime = mSeekTask->GetSeekTarget().GetTime().ToMicroseconds();
- int64_t newCurrentTime = seekTime;
-
- // Setup timestamp state.
- RefPtr<MediaData> video = mMaster->VideoQueue().PeekFront();
- if (seekTime == mMaster->Duration().ToMicroseconds()) {
+ int64_t newCurrentTime;
+
+ // For the accurate seek, we always set the newCurrentTime = seekTime so that
+ // the updated HTMLMediaElement.currentTime will always be the seek target;
+ // we rely on the MediaSink to handles the gap between the newCurrentTime and
+ // the real decoded samples' start time.
+ // For the other seek types, we update the newCurrentTime with the decoded
+ // samples, set it to be the smallest start time of decoded samples.
+ if (mSeekTask->GetSeekTarget().IsAccurate()) {
newCurrentTime = seekTime;
- } else if (mMaster->HasAudio()) {
+ } else {
RefPtr<MediaData> audio = mMaster->AudioQueue().PeekFront();
- // Though we adjust the newCurrentTime in audio-based, and supplemented
- // by video. For better UX, should NOT bind the slide position to
- // the first audio data timestamp directly.
- // While seeking to a position where there's only either audio or video, or
- // seeking to a position lies before audio or video, we need to check if
- // seekTime is bounded in suitable duration. See Bug 1112438.
- int64_t audioStart = audio ? audio->mTime : seekTime;
- // We only pin the seek time to the video start time if the video frame
- // contains the seek time.
- if (video && video->mTime <= seekTime && video->GetEndTime() > seekTime) {
- newCurrentTime = std::min(audioStart, video->mTime);
- } else {
- newCurrentTime = audioStart;
+ RefPtr<MediaData> video = mMaster->VideoQueue().PeekFront();
+ const int64_t audioStart = audio ? audio->mTime : INT64_MAX;
+ const int64_t videoStart = video ? video->mTime : INT64_MAX;
+ newCurrentTime = std::min(audioStart, videoStart);
+ if (newCurrentTime == INT64_MAX) {
+ newCurrentTime = seekTime;
}
- } else {
- newCurrentTime = video ? video->mTime : seekTime;
}
// Change state to DECODING or COMPLETED now.
bool isLiveStream = Resource()->IsLiveStream();
State nextState;
if (newCurrentTime == mMaster->Duration().ToMicroseconds() && !isLiveStream) {
// Seeked to end of media, move to COMPLETED state. Note we don't do
// this when playing a live stream, since the end of media will advance
@@ -1509,17 +1504,17 @@ SeekingState::SeekCompleted()
// Otherwise we might have |newCurrentTime > mMediaSink->GetPosition()|
// and fail the assertion in GetClock() since we didn't stop MediaSink.
mMaster->UpdatePlaybackPositionInternal(newCurrentTime);
}
// Try to decode another frame to detect if we're at the end...
SLOG("Seek completed, mCurrentPosition=%lld", mMaster->mCurrentPosition.Ref());
- if (video) {
+ if (mMaster->VideoQueue().PeekFront()) {
mMaster->mMediaSink->Redraw(Info().mVideo);
mMaster->mOnPlaybackEvent.Notify(MediaEventType::Invalidate);
}
if (mVisibility == EventVisibility::Observable) {
mMaster->UpdateNextFrameStatus();
}
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1955,26 +1955,18 @@ MediaFormatReader::Seek(SeekTarget aTarg
return p;
}
void
MediaFormatReader::SetSeekTarget(const SeekTarget& aTarget)
{
MOZ_ASSERT(OnTaskQueue());
- SeekTarget target = aTarget;
-
- // Transform the seek target time to the demuxer timeline.
- if (!ForceZeroStartTime()) {
- target.SetTime(aTarget.GetTime() - TimeUnit::FromMicroseconds(StartTime())
- + mInfo.mStartTime);
- }
-
- mOriginalSeekTarget = target;
- mFallbackSeekTime = mPendingSeekTime = Some(target.GetTime());
+ mOriginalSeekTarget = aTarget;
+ mFallbackSeekTime = mPendingSeekTime = Some(aTarget.GetTime());
}
void
MediaFormatReader::ScheduleSeek()
{
if (mSeekScheduled) {
return;
}