зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1319992: P3. Remove no longer used seeking argument. r=jwwang
MozReview-Commit-ID: 9Oc0SHX0Rw2 --HG-- extra : rebase_source : 845ab6daa4414e57d5ce02dee1424df29d3b962d
This commit is contained in:
Родитель
a64614f927
Коммит
20853d0607
|
@ -151,10 +151,8 @@ public:
|
|||
// 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) {}
|
||||
|
||||
|
|
|
@ -121,16 +121,15 @@ MediaDecoderReaderWrapper::IsWaitingVideoData() const
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -67,8 +67,7 @@ public:
|
|||
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();
|
||||
|
|
|
@ -1013,7 +1013,7 @@ private:
|
|||
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);
|
||||
|
|
|
@ -2270,7 +2270,7 @@ MediaFormatReader::OnVideoSkipFailed(MediaTrackDemuxer::SkipFailureHolder aFailu
|
|||
}
|
||||
|
||||
RefPtr<MediaDecoderReader::SeekPromise>
|
||||
MediaFormatReader::Seek(const SeekTarget& aTarget, int64_t aUnused)
|
||||
MediaFormatReader::Seek(const SeekTarget& aTarget)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
|
|
|
@ -46,8 +46,7 @@ public:
|
|||
|
||||
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;
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -313,7 +313,7 @@ bool AndroidMediaReader::DecodeAudioData()
|
|||
}
|
||||
|
||||
RefPtr<MediaDecoderReader::SeekPromise>
|
||||
AndroidMediaReader::Seek(const SeekTarget& aTarget, int64_t aEndTime)
|
||||
AndroidMediaReader::Seek(const SeekTarget& aTarget)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
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;
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ DirectShowReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
|||
}
|
||||
|
||||
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)) {
|
||||
|
|
|
@ -57,8 +57,7 @@ public:
|
|||
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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче