Bug 1319992: P3. Remove no longer used seeking argument. r=jwwang
MozReview-Commit-ID: 9Oc0SHX0Rw2
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -146,20 +146,18 @@ public:
// synchronous ReadMetadata() calls. Implementations may also
// override AsyncReadMetadata to create a more proper async implementation.
virtual RefPtr<MetadataPromise> AsyncReadMetadata();
// Fills aInfo with the latest cached data required to present the media,
// ReadUpdatedMetadata will always be called once ReadMetadata has succeeded.
virtual void ReadUpdatedMetadata(MediaInfo* aInfo) {}
- // Moves the decode head to aTime microseconds. aEndTime denotes the end
- // time of the media in usecs. This is only needed for OggReader, and should
- // probably be removed somehow.
- virtual RefPtr<SeekPromise> Seek(const SeekTarget& aTarget, int64_t aEndTime) = 0;
+ // Moves the decode head to aTime microseconds.
+ virtual RefPtr<SeekPromise> Seek(const SeekTarget& aTarget) = 0;
virtual void SetCDMProxy(CDMProxy* aProxy) {}
// Tell the reader that the data decoded are not for direct playback, so it
// can accept more files, in particular those which have more channels than
// available in the audio output.
void SetIgnoreAudioOutputFormat()
{
--- a/dom/media/MediaDecoderReaderWrapper.cpp
+++ b/dom/media/MediaDecoderReaderWrapper.cpp
@@ -116,26 +116,25 @@ MediaDecoderReaderWrapper::IsWaitingAudi
bool
MediaDecoderReaderWrapper::IsWaitingVideoData() const
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
return mVideoWaitRequest.Exists();
}
RefPtr<MediaDecoderReader::SeekPromise>
-MediaDecoderReaderWrapper::Seek(const SeekTarget& aTarget,
- const media::TimeUnit& aEndTime)
+MediaDecoderReaderWrapper::Seek(const SeekTarget& aTarget)
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
SeekTarget adjustedTarget = aTarget;
adjustedTarget.SetTime(adjustedTarget.GetTime() + StartTime());
- return InvokeAsync<SeekTarget&&, int64_t>(
+ return InvokeAsync<SeekTarget&&>(
mReader->OwnerThread(), mReader.get(), __func__,
&MediaDecoderReader::Seek,
- Move(adjustedTarget), aEndTime.ToMicroseconds());
+ Move(adjustedTarget));
}
void
MediaDecoderReaderWrapper::WaitForData(MediaData::Type aType)
{
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
auto p = InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
--- a/dom/media/MediaDecoderReaderWrapper.h
+++ b/dom/media/MediaDecoderReaderWrapper.h
@@ -62,18 +62,17 @@ public:
// NOTE: please set callbacks before invoking WaitForData()!
void WaitForData(MediaData::Type aType);
bool IsRequestingAudioData() const;
bool IsRequestingVideoData() const;
bool IsWaitingAudioData() const;
bool IsWaitingVideoData() const;
- RefPtr<SeekPromise> Seek(const SeekTarget& aTarget,
- const media::TimeUnit& aEndTime);
+ RefPtr<SeekPromise> Seek(const SeekTarget& aTarget);
RefPtr<ShutdownPromise> Shutdown();
void ReleaseResources();
void ResetDecode(TrackSet aTracks);
nsresult Init() { return mReader->Init(); }
bool IsWaitForDataSupported() const { return mReader->IsWaitForDataSupported(); }
bool IsAsync() const { return mReader->IsAsync(); }
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1008,17 +1008,17 @@ private:
} else {
mMaster->Reset();
}
}
void DoSeek() override
{
// Request the demuxer to perform seek.
- mSeekRequest.Begin(Reader()->Seek(mSeekJob.mTarget.ref(), mMaster->Duration())
+ mSeekRequest.Begin(Reader()->Seek(mSeekJob.mTarget.ref())
->Then(OwnerThread(), __func__,
[this] (media::TimeUnit aUnit) {
OnSeekResolved(aUnit);
},
[this] (const MediaResult& aError) {
OnSeekRejected(aError);
}));
}
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -2265,17 +2265,17 @@ MediaFormatReader::OnVideoSkipFailed(Med
break;
default:
NotifyError(TrackType::kVideoTrack, aFailure.mFailure);
break;
}
}
RefPtr<MediaDecoderReader::SeekPromise>
-MediaFormatReader::Seek(const SeekTarget& aTarget, int64_t aUnused)
+MediaFormatReader::Seek(const SeekTarget& aTarget)
{
MOZ_ASSERT(OnTaskQueue());
LOG("aTarget=(%lld)", aTarget.GetTime().ToMicroseconds());
MOZ_DIAGNOSTIC_ASSERT(mSeekPromise.IsEmpty());
MOZ_DIAGNOSTIC_ASSERT(!mVideo.HasPromise());
MOZ_DIAGNOSTIC_ASSERT(aTarget.IsVideoOnly() || !mAudio.HasPromise());
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -41,18 +41,17 @@ public:
RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThreshold) override;
RefPtr<MediaDataPromise> RequestAudioData() override;
RefPtr<MetadataPromise> AsyncReadMetadata() override;
void ReadUpdatedMetadata(MediaInfo* aInfo) override;
- RefPtr<SeekPromise>
- Seek(const SeekTarget& aTarget, int64_t aUnused) override;
+ RefPtr<SeekPromise> Seek(const SeekTarget& aTarget) override;
protected:
void NotifyDataArrived() override;
void UpdateBuffered() override;
public:
bool ForceZeroStartTime() const override;
new file mode 100644
--- /dev/null
+++ b/dom/media/NextFrameSeekTask.cpp
@@ -0,0 +1,327 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "NextFrameSeekTask.h"
+#include "MediaDecoderReaderWrapper.h"
+#include "mozilla/AbstractThread.h"
+#include "mozilla/Assertions.h"
+#include "nsPrintfCString.h"
+
+namespace mozilla {
+
+extern LazyLogModule gMediaSampleLog;
+
+#define SAMPLE_LOG(x, ...) MOZ_LOG(gMediaSampleLog, LogLevel::Debug, \
+ ("[NextFrameSeekTask] Decoder=%p " x, mDecoderID, ##__VA_ARGS__))
+
+namespace media {
+
+NextFrameSeekTask::NextFrameSeekTask(const void* aDecoderID,
+ AbstractThread* aThread,
+ MediaDecoderReaderWrapper* aReader,
+ const SeekTarget& aTarget,
+ const MediaInfo& aInfo,
+ const media::TimeUnit& aDuration,
+ int64_t aCurrentTime,
+ MediaQueue<MediaData>& aAudioQueue,
+ MediaQueue<MediaData>& aVideoQueue)
+ : SeekTask(aDecoderID, aThread, aReader, aTarget)
+ , mAudioQueue(aAudioQueue)
+ , mVideoQueue(aVideoQueue)
+ , mCurrentTime(aCurrentTime)
+ , mDuration(aDuration)
+{
+ AssertOwnerThread();
+ MOZ_ASSERT(aInfo.HasVideo());
+}
+
+NextFrameSeekTask::~NextFrameSeekTask()
+{
+ AssertOwnerThread();
+ MOZ_ASSERT(mIsDiscarded);
+}
+
+void
+NextFrameSeekTask::Discard()
+{
+ AssertOwnerThread();
+
+ // Disconnect MDSM.
+ RejectIfExist(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
+
+ mIsDiscarded = true;
+}
+
+int64_t
+NextFrameSeekTask::CalculateNewCurrentTime() const
+{
+ AssertOwnerThread();
+
+ // The HTMLMediaElement.currentTime should be updated to the seek target
+ // which has been updated to the next frame's time.
+ return mTarget.GetTime().ToMicroseconds();
+}
+
+void
+NextFrameSeekTask::HandleAudioDecoded(MediaData* aAudio)
+{
+ AssertOwnerThread();
+ MOZ_ASSERT(aAudio);
+ MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
+
+ // The MDSM::mDecodedAudioEndTime will be updated once the whole SeekTask is
+ // resolved.
+
+ SAMPLE_LOG("OnAudioDecoded [%lld,%lld]", aAudio->mTime, aAudio->GetEndTime());
+
+ // We accept any audio data here.
+ mSeekedAudioData = aAudio;
+
+ MaybeFinishSeek();
+}
+
+void
+NextFrameSeekTask::HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart)
+{
+ AssertOwnerThread();
+ MOZ_ASSERT(aVideo);
+ MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
+
+ // The MDSM::mDecodedVideoEndTime will be updated once the whole SeekTask is
+ // resolved.
+
+ SAMPLE_LOG("OnVideoDecoded [%lld,%lld]", aVideo->mTime, aVideo->GetEndTime());
+
+ if (aVideo->mTime > mCurrentTime) {
+ mSeekedVideoData = aVideo;
+ }
+
+ if (NeedMoreVideo()) {
+ RequestVideoData();
+ return;
+ }
+
+ MaybeFinishSeek();
+}
+
+void
+NextFrameSeekTask::HandleNotDecoded(MediaData::Type aType, const MediaResult& aError)
+{
+ AssertOwnerThread();
+ switch (aType) {
+ case MediaData::AUDIO_DATA:
+ {
+ MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
+
+ SAMPLE_LOG("OnAudioNotDecoded (aError=%u)", aError.Code());
+
+ // We don't really handle audio deocde error here. Let MDSM to trigger further
+ // audio decoding tasks if it needs to play audio, and MDSM will then receive
+ // the decoding state from MediaDecoderReader.
+
+ MaybeFinishSeek();
+ break;
+ }
+ case MediaData::VIDEO_DATA:
+ {
+ MOZ_ASSERT(!mSeekTaskPromise.IsEmpty(), "Seek shouldn't be finished");
+
+ SAMPLE_LOG("OnVideoNotDecoded (aError=%u)", aError.Code());
+
+ if (aError == NS_ERROR_DOM_MEDIA_END_OF_STREAM) {
+ mIsVideoQueueFinished = true;
+ }
+
+ // Video seek not finished.
+ if (NeedMoreVideo()) {
+ switch (aError.Code()) {
+ case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
+ mReader->WaitForData(MediaData::VIDEO_DATA);
+ break;
+ case NS_ERROR_DOM_MEDIA_CANCELED:
+ RequestVideoData();
+ break;
+ case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
+ MOZ_ASSERT(false, "Shouldn't want more data for ended video.");
+ break;
+ default:
+ // Reject the promise since we can't finish video seek anyway.
+ RejectIfExist(aError, __func__);
+ break;
+ }
+ return;
+ }
+
+ MaybeFinishSeek();
+ break;
+ }
+ default:
+ MOZ_ASSERT_UNREACHABLE("We cannot handle RAW_DATA or NULL_DATA here.");
+ }
+}
+
+void
+NextFrameSeekTask::HandleAudioWaited(MediaData::Type aType)
+{
+ AssertOwnerThread();
+
+ // We don't make an audio decode request here, instead, let MDSM to
+ // trigger further audio decode tasks if MDSM itself needs to play audio.
+ MaybeFinishSeek();
+}
+
+void
+NextFrameSeekTask::HandleVideoWaited(MediaData::Type aType)
+{
+ AssertOwnerThread();
+
+ if (NeedMoreVideo()) {
+ RequestVideoData();
+ return;
+ }
+ MaybeFinishSeek();
+}
+
+void
+NextFrameSeekTask::HandleNotWaited(const WaitForDataRejectValue& aRejection)
+{
+ AssertOwnerThread();
+
+ switch(aRejection.mType) {
+ case MediaData::AUDIO_DATA:
+ {
+ // We don't make an audio decode request here, instead, let MDSM to
+ // trigger further audio decode tasks if MDSM itself needs to play audio.
+ MaybeFinishSeek();
+ break;
+ }
+ case MediaData::VIDEO_DATA:
+ {
+ if (NeedMoreVideo()) {
+ // Reject if we can't finish video seeking.
+ RejectIfExist(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
+ return;
+ }
+ MaybeFinishSeek();
+ break;
+ }
+ default:
+ MOZ_ASSERT_UNREACHABLE("We cannot handle RAW_DATA or NULL_DATA here.");
+ }
+}
+
+/*
+ * Remove samples from the queue until aCompare() returns false.
+ * aCompare A function object with the signature bool(int64_t) which returns
+ * true for samples that should be removed.
+ */
+template <typename Function> static void
+DiscardFrames(MediaQueue<MediaData>& aQueue, const Function& aCompare)
+{
+ while(aQueue.GetSize() > 0) {
+ if (aCompare(aQueue.PeekFront()->mTime)) {
+ RefPtr<MediaData> releaseMe = aQueue.PopFront();
+ continue;
+ }
+ break;
+ }
+}
+
+RefPtr<NextFrameSeekTask::SeekTaskPromise>
+NextFrameSeekTask::Seek()
+{
+ AssertOwnerThread();
+
+ auto currentTime = mCurrentTime;
+ DiscardFrames(mVideoQueue, [currentTime] (int64_t aSampleTime) {
+ return aSampleTime <= currentTime;
+ });
+
+ RefPtr<SeekTaskPromise> promise = mSeekTaskPromise.Ensure(__func__);
+ if (!IsVideoRequestPending() && NeedMoreVideo()) {
+ RequestVideoData();
+ }
+ MaybeFinishSeek(); // Might resolve mSeekTaskPromise and modify audio queue.
+ return promise;
+}
+
+void
+NextFrameSeekTask::RequestVideoData()
+{
+ AssertOwnerThread();
+ mReader->RequestVideoData(false, media::TimeUnit());
+}
+
+bool
+NextFrameSeekTask::NeedMoreVideo() const
+{
+ AssertOwnerThread();
+ // Need to request video when we have none and video queue is not finished.
+ return mVideoQueue.GetSize() == 0 &&
+ !mSeekedVideoData &&
+ !mVideoQueue.IsFinished() &&
+ !mIsVideoQueueFinished;
+}
+
+bool
+NextFrameSeekTask::IsVideoRequestPending() const
+{
+ AssertOwnerThread();
+ return mReader->IsRequestingVideoData() || mReader->IsWaitingVideoData();
+}
+
+bool
+NextFrameSeekTask::IsAudioSeekComplete() const
+{
+ AssertOwnerThread();
+ // Don't finish seek until there are no pending requests. Otherwise, we might
+ // lose audio samples for the promise is resolved asynchronously.
+ return !mReader->IsRequestingAudioData() && !mReader->IsWaitingAudioData();
+}
+
+bool
+NextFrameSeekTask::IsVideoSeekComplete() const
+{
+ AssertOwnerThread();
+ // Don't finish seek until there are no pending requests. Otherwise, we might
+ // lose video samples for the promise is resolved asynchronously.
+ return !IsVideoRequestPending() && !NeedMoreVideo();
+}
+
+void
+NextFrameSeekTask::MaybeFinishSeek()
+{
+ AssertOwnerThread();
+ if (IsAudioSeekComplete() && IsVideoSeekComplete()) {
+ UpdateSeekTargetTime();
+
+ auto time = mTarget.GetTime().ToMicroseconds();
+ DiscardFrames(mAudioQueue, [time] (int64_t aSampleTime) {
+ return aSampleTime < time;
+ });
+
+ Resolve(__func__); // Call to MDSM::SeekCompleted();
+ }
+}
+
+void
+NextFrameSeekTask::UpdateSeekTargetTime()
+{
+ AssertOwnerThread();
+
+ RefPtr<MediaData> data = mVideoQueue.PeekFront();
+ if (data) {
+ mTarget.SetTime(TimeUnit::FromMicroseconds(data->mTime));
+ } else if (mSeekedVideoData) {
+ mTarget.SetTime(TimeUnit::FromMicroseconds(mSeekedVideoData->mTime));
+ } else if (mIsVideoQueueFinished || mVideoQueue.AtEndOfStream()) {
+ mTarget.SetTime(mDuration);
+ } else {
+ MOZ_ASSERT(false, "No data!");
+ }
+}
+} // namespace media
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/NextFrameSeekTask.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef NEXTFRAME_SEEK_TASK_H
+#define NEXTFRAME_SEEK_TASK_H
+
+#include "SeekTask.h"
+#include "MediaDecoderReader.h"
+
+namespace mozilla {
+namespace media {
+
+/*
+ * While invoking a NextFrameSeekTask, we don't know the seek target time, what
+ * we know is the media's currant position. We use the media's currant position
+ * to find out what the next frame is, by traversing through the video queue or
+ * asking the decoder to decode more video frames. Once we confirm the next
+ * frame, we then know the target time of the NextFrameSeekTask and we update it
+ * so that the MDSM will be able to update the media element's position.
+ */
+
+class NextFrameSeekTask final : public SeekTask {
+public:
+ NextFrameSeekTask(const void* aDecoderID,
+ AbstractThread* aThread,
+ MediaDecoderReaderWrapper* aReader,
+ const SeekTarget& aTarget,
+ const MediaInfo& aInfo,
+ const media::TimeUnit& aDuration,
+ int64_t aCurrentTime,
+ MediaQueue<MediaData>& aAudioQueue,
+ MediaQueue<MediaData>& aVideoQueue);
+
+ void Discard() override;
+
+ RefPtr<SeekTaskPromise> Seek() override;
+
+ int64_t CalculateNewCurrentTime() const override;
+
+ void HandleAudioDecoded(MediaData* aAudio) override;
+
+ void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override;
+
+ void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) override;
+
+ void HandleAudioWaited(MediaData::Type aType) override;
+
+ void HandleVideoWaited(MediaData::Type aType) override;
+
+ void HandleNotWaited(const WaitForDataRejectValue& aRejection) override;
+
+ ~NextFrameSeekTask();
+
+ void RequestVideoData();
+
+ bool NeedMoreVideo() const;
+
+ bool IsVideoRequestPending() const;
+
+ bool IsAudioSeekComplete() const;
+
+ bool IsVideoSeekComplete() const;
+
+ void MaybeFinishSeek();
+
+ // Update the seek target's time before resolving this seek task, the updated
+ // time will be used in the MDSM::SeekCompleted() to update the MDSM's position.
+ void UpdateSeekTargetTime();
+
+ /*
+ * Data shared with MDSM.
+ */
+ MediaQueue<MediaData>& mAudioQueue;
+ MediaQueue<MediaData>& mVideoQueue;
+
+ /*
+ * Internal state.
+ */
+ const int64_t mCurrentTime;
+ media::TimeUnit mDuration;
+};
+
+} // namespace media
+} // namespace mozilla
+
+#endif /* NEXTFRAME_SEEK_TASK_H */
new file mode 100644
--- /dev/null
+++ b/dom/media/SeekTask.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SEEK_TASK_H
+#define SEEK_TASK_H
+
+#include "mozilla/MozPromise.h"
+#include "MediaData.h" // For MediaData::Type.
+#include "MediaDecoderReader.h" // For WaitForDataRejectValue.
+#include "MediaResult.h"
+#include "SeekTarget.h"
+
+namespace mozilla {
+
+class AbstractThread;
+class MediaData;
+class MediaDecoderReaderWrapper;
+
+namespace media {
+class TimeUnit;
+}
+
+struct SeekTaskResolveValue
+{
+ RefPtr<MediaData> mSeekedAudioData;
+ RefPtr<MediaData> mSeekedVideoData;
+ bool mIsAudioQueueFinished;
+ bool mIsVideoQueueFinished;
+};
+
+struct SeekTaskRejectValue
+{
+ SeekTaskRejectValue()
+ : mIsAudioQueueFinished(false)
+ , mIsVideoQueueFinished(false)
+ , mError(NS_ERROR_DOM_MEDIA_FATAL_ERR)
+ {
+ }
+ bool mIsAudioQueueFinished;
+ bool mIsVideoQueueFinished;
+ MediaResult mError;
+};
+
+class SeekTask {
+
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SeekTask)
+
+public:
+ static const bool IsExclusive = true;
+
+ using SeekTaskPromise =
+ MozPromise<SeekTaskResolveValue, SeekTaskRejectValue, IsExclusive>;
+
+ virtual void Discard() = 0;
+
+ virtual RefPtr<SeekTaskPromise> Seek() = 0;
+
+ virtual int64_t CalculateNewCurrentTime() const = 0;
+
+ virtual void HandleAudioDecoded(MediaData* aAudio) = 0;
+
+ virtual void HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) = 0;
+
+ virtual void HandleNotDecoded(MediaData::Type aType, const MediaResult& aError) = 0;
+
+ virtual void HandleAudioWaited(MediaData::Type aType) = 0;
+
+ virtual void HandleVideoWaited(MediaData::Type aType) = 0;
+
+ virtual void HandleNotWaited(const WaitForDataRejectValue& aRejection) = 0;
+
+protected:
+ SeekTask(const void* aDecoderID,
+ AbstractThread* aThread,
+ MediaDecoderReaderWrapper* aReader,
+ const SeekTarget& aTarget);
+
+ virtual ~SeekTask();
+
+public:
+ void Resolve(const char* aCallSite);
+
+ void RejectIfExist(const MediaResult& aError, const char* aCallSite);
+
+ void AssertOwnerThread() const;
+
+ AbstractThread* OwnerThread() const;
+
+ /*
+ * Data shared with MDSM.
+ */
+ const void* mDecoderID; // For logging.
+ const RefPtr<AbstractThread> mOwnerThread;
+ const RefPtr<MediaDecoderReaderWrapper> mReader;
+
+ /*
+ * Internal state.
+ */
+ SeekTarget mTarget;
+ MozPromiseHolder<SeekTaskPromise> mSeekTaskPromise;
+ bool mIsDiscarded;
+
+ /*
+ * Information which are going to be returned to MDSM.
+ */
+ RefPtr<MediaData> mSeekedAudioData;
+ RefPtr<MediaData> mSeekedVideoData;
+ bool mIsAudioQueueFinished;
+ bool mIsVideoQueueFinished;
+};
+
+} // namespace mozilla
+
+#endif /* SEEK_TASK_H */
--- a/dom/media/android/AndroidMediaReader.cpp
+++ b/dom/media/android/AndroidMediaReader.cpp
@@ -308,17 +308,17 @@ bool AndroidMediaReader::DecodeAudioData
frames,
source.mAudioChannels,
MPCopy(static_cast<uint8_t *>(source.mData),
source.mSize,
source.mAudioChannels));
}
RefPtr<MediaDecoderReader::SeekPromise>
-AndroidMediaReader::Seek(const SeekTarget& aTarget, int64_t aEndTime)
+AndroidMediaReader::Seek(const SeekTarget& aTarget)
{
MOZ_ASSERT(OnTaskQueue());
RefPtr<SeekPromise> p = mSeekPromise.Ensure(__func__);
if (mHasAudio && mHasVideo) {
// The decoder seeks/demuxes audio and video streams separately. So if
// we seek both audio and video to aTarget, the audio stream can typically
// seek closer to the seek target, since typically every audio block is
--- a/dom/media/android/AndroidMediaReader.h
+++ b/dom/media/android/AndroidMediaReader.h
@@ -43,17 +43,17 @@ public:
nsresult ResetDecode(TrackSet aTracks = TrackSet(TrackInfo::kAudioTrack,
TrackInfo::kVideoTrack)) override;
bool DecodeAudioData() override;
bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) override;
nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) override;
- RefPtr<SeekPromise> Seek(const SeekTarget& aTarget, int64_t aEndTime) override;
+ RefPtr<SeekPromise> Seek(const SeekTarget& aTarget) override;
RefPtr<ShutdownPromise> Shutdown() override;
class ImageBufferCallback : public MPAPI::BufferCallback {
typedef mozilla::layers::Image Image;
public:
ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer);
--- a/dom/media/directshow/DirectShowReader.cpp
+++ b/dom/media/directshow/DirectShowReader.cpp
@@ -315,17 +315,17 @@ bool
DirectShowReader::DecodeVideoFrame(bool &aKeyframeSkip,
int64_t aTimeThreshold)
{
MOZ_ASSERT(OnTaskQueue());
return false;
}
RefPtr<MediaDecoderReader::SeekPromise>
-DirectShowReader::Seek(const SeekTarget& aTarget, int64_t aEndTime)
+DirectShowReader::Seek(const SeekTarget& aTarget)
{
nsresult res = SeekInternal(aTarget.GetTime().ToMicroseconds());
if (NS_FAILED(res)) {
return SeekPromise::CreateAndReject(res, __func__);
} else {
return SeekPromise::CreateAndResolve(aTarget.GetTime(), __func__);
}
}
--- a/dom/media/directshow/DirectShowReader.h
+++ b/dom/media/directshow/DirectShowReader.h
@@ -52,18 +52,17 @@ public:
bool DecodeAudioData() override;
bool DecodeVideoFrame(bool &aKeyframeSkip,
int64_t aTimeThreshold) override;
nsresult ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags) override;
- RefPtr<SeekPromise>
- Seek(const SeekTarget& aTarget, int64_t aEndTime) override;
+ RefPtr<SeekPromise> Seek(const SeekTarget& aTarget) override;
static const GUID CLSID_MPEG_LAYER_3_DECODER_FILTER;
private:
// Notifies the filter graph that playback is complete. aStatus is
// the code to send to the filter graph. Always returns false, so
// that we can just "return Finish()" from DecodeAudioData().
bool Finish(HRESULT aStatus);