author | Kaku Kuo <tkuo@mozilla.com> |
Mon, 16 May 2016 18:15:17 +0800 | |
changeset 298099 | fb8ee867138d4b92ddd3efbf39a755b0fe7eb272 |
parent 298098 | e5e3a65e822049305fcf019b69bc1370bf8f091c |
child 298100 | 2292661153e3b6ecf94cecf63af8a66950f849e9 |
push id | 77035 |
push user | ryanvm@gmail.com |
push date | Thu, 19 May 2016 13:52:35 +0000 |
treeherder | mozilla-inbound@fb8ee867138d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jya |
bugs | 1272267 |
milestone | 49.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/media/MediaFormatReader.cpp | file | annotate | diff | comparison | revisions | |
dom/media/MediaFormatReader.h | file | annotate | diff | comparison | revisions |
--- a/dom/media/MediaFormatReader.cpp +++ b/dom/media/MediaFormatReader.cpp @@ -924,16 +924,21 @@ MediaFormatReader::HandleDemuxedSamples( NotifyError(aTrack); return; } if (!EnsureDecoderInitialized(aTrack)) { return; } + if (!ForceZeroStartTime() && decoder.mFirstDemuxedSampleTime.isNothing()) { + decoder.mFirstDemuxedSampleTime.emplace( + media::TimeUnit::FromMicroseconds(decoder.mQueuedSamples[0]->mTime)); + } + LOGV("Giving %s input to decoder", TrackTypeToStr(aTrack)); // Decode all our demuxed frames. bool samplesPending = false; while (decoder.mQueuedSamples.Length()) { RefPtr<MediaRawData> sample = decoder.mQueuedSamples[0]; RefPtr<SharedTrackInfo> info = sample->mTrackInfo; @@ -1506,27 +1511,59 @@ MediaFormatReader::Seek(SeekTarget aTarg LOG("Seek() END (Unseekable)"); return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); } if (mShutdown) { return SeekPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); } - mOriginalSeekTarget = aTarget; - mFallbackSeekTime = mPendingSeekTime = Some(aTarget.GetTime()); + SetSeekTarget(Move(aTarget)); RefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__); ScheduleSeek(); 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()) + + DemuxStartTime()); + } + + mOriginalSeekTarget = target; + mFallbackSeekTime = mPendingSeekTime = Some(target.GetTime()); +} + +TimeUnit +MediaFormatReader::DemuxStartTime() +{ + MOZ_ASSERT(OnTaskQueue()); + MOZ_ASSERT(!ForceZeroStartTime()); + MOZ_ASSERT((!HasAudio() || mAudio.mFirstDemuxedSampleTime.isSome()) && + (!HasVideo() || mVideo.mFirstDemuxedSampleTime.isSome())); + + return std::min(HasAudio() + ? mAudio.mFirstDemuxedSampleTime.ref() + : TimeUnit::FromInfinity(), + HasVideo() + ? mVideo.mFirstDemuxedSampleTime.ref() + : TimeUnit::FromInfinity()); +} + +void MediaFormatReader::ScheduleSeek() { if (mSeekScheduled) { return; } mSeekScheduled = true; OwnerThread()->Dispatch(NewRunnableMethod(this, &MediaFormatReader::AttemptSeek)); }
--- a/dom/media/MediaFormatReader.h +++ b/dom/media/MediaFormatReader.h @@ -396,16 +396,17 @@ private: // This value is updated after a frame is successfully decoded. Atomic<bool> mIsHardwareAccelerated; // Sample format monitoring. uint32_t mLastStreamSourceID; Maybe<uint32_t> mNextStreamSourceID; media::TimeIntervals mTimeRanges; Maybe<media::TimeUnit> mLastTimeRangesEnd; RefPtr<SharedTrackInfo> mInfo; + Maybe<media::TimeUnit> mFirstDemuxedSampleTime; }; class DecoderDataWithPromise : public DecoderData { public: DecoderDataWithPromise(MediaFormatReader* aOwner, MediaData::Type aType, uint32_t aDecodeAhead) : DecoderData(aOwner, aType, aDecodeAhead) @@ -501,16 +502,18 @@ private: // Set to true if any of our track buffers may be blocking. bool mTrackDemuxersMayBlock; // Set the demuxed-only flag. Atomic<bool> mDemuxOnly; // Seeking objects. + void SetSeekTarget(const SeekTarget& aTarget); + media::TimeUnit DemuxStartTime(); bool IsSeeking() const { return mPendingSeekTime.isSome(); } bool IsVideoSeeking() const { return IsSeeking() && mOriginalSeekTarget.IsVideoOnly(); } void ScheduleSeek(); void AttemptSeek(); void OnSeekFailed(TrackType aTrack, DemuxerFailureReason aFailure);