зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1324629
. Part 2 - remove video callback. r=kaku
MozReview-Commit-ID: 92t6GoznxL5 --HG-- extra : rebase_source : b1bf9053a396c501c918b8848d98ce920e3f09f6 extra : intermediate-source : 41414e1780251a382e900bb9ef5c011074278875 extra : source : 89fd50a16e61f3bfdfe445e1b49238ada801256b
This commit is contained in:
Родитель
6965b449bf
Коммит
08a93dbdc4
|
@ -54,43 +54,26 @@ MediaDecoderReaderWrapper::RequestAudioData()
|
|||
[] (const MediaResult& aError) {});
|
||||
}
|
||||
|
||||
void
|
||||
RefPtr<MediaDecoderReaderWrapper::MediaDataPromise>
|
||||
MediaDecoderReaderWrapper::RequestVideoData(bool aSkipToNextKeyframe,
|
||||
media::TimeUnit aTimeThreshold)
|
||||
{
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
MOZ_ASSERT(!mShutdown);
|
||||
|
||||
// Time the video decode and send this value back to callbacks who accept
|
||||
// a TimeStamp as its second parameter.
|
||||
TimeStamp videoDecodeStartTime = TimeStamp::Now();
|
||||
|
||||
if (aTimeThreshold.ToMicroseconds() > 0) {
|
||||
aTimeThreshold += StartTime();
|
||||
}
|
||||
|
||||
auto p = InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::RequestVideoData,
|
||||
aSkipToNextKeyframe, aTimeThreshold.ToMicroseconds());
|
||||
|
||||
RefPtr<MediaDecoderReaderWrapper> self = this;
|
||||
mVideoDataRequest.Begin(p->Then(mOwnerThread, __func__,
|
||||
[self, videoDecodeStartTime] (MediaData* aVideoSample) {
|
||||
self->mVideoDataRequest.Complete();
|
||||
aVideoSample->AdjustForStartTime(self->StartTime().ToMicroseconds());
|
||||
self->mVideoCallback.Notify(AsVariant(MakeTuple(aVideoSample, videoDecodeStartTime)));
|
||||
},
|
||||
[self] (const MediaResult& aError) {
|
||||
self->mVideoDataRequest.Complete();
|
||||
self->mVideoCallback.Notify(AsVariant(aError));
|
||||
}));
|
||||
}
|
||||
|
||||
bool
|
||||
MediaDecoderReaderWrapper::IsRequestingVideoData() const
|
||||
{
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
return mVideoDataRequest.Exists();
|
||||
int64_t startTime = StartTime().ToMicroseconds();
|
||||
return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::RequestVideoData,
|
||||
aSkipToNextKeyframe, aTimeThreshold.ToMicroseconds())
|
||||
->Then(mOwnerThread, __func__,
|
||||
[startTime] (MediaData* aVideo) {
|
||||
aVideo->AdjustForStartTime(startTime);
|
||||
},
|
||||
[] (const MediaResult& aError) {});
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -172,7 +155,6 @@ MediaDecoderReaderWrapper::ResetDecode(TrackSet aTracks)
|
|||
}
|
||||
|
||||
if (aTracks.contains(TrackInfo::kVideoTrack)) {
|
||||
mVideoDataRequest.DisconnectIfExists();
|
||||
mVideoWaitRequest.DisconnectIfExists();
|
||||
}
|
||||
|
||||
|
@ -187,8 +169,6 @@ RefPtr<ShutdownPromise>
|
|||
MediaDecoderReaderWrapper::Shutdown()
|
||||
{
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
MOZ_ASSERT(!mVideoDataRequest.Exists());
|
||||
|
||||
mShutdown = true;
|
||||
return InvokeAsync(mReader->OwnerThread(), mReader.get(), __func__,
|
||||
&MediaDecoderReader::Shutdown);
|
||||
|
|
|
@ -38,7 +38,6 @@ class MediaDecoderReaderWrapper {
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReaderWrapper);
|
||||
|
||||
private:
|
||||
MediaCallbackExc<VideoCallbackData> mVideoCallback;
|
||||
MediaCallbackExc<WaitCallbackData> mAudioWaitCallback;
|
||||
MediaCallbackExc<WaitCallbackData> mVideoWaitCallback;
|
||||
|
||||
|
@ -49,18 +48,18 @@ public:
|
|||
media::TimeUnit StartTime() const;
|
||||
RefPtr<MetadataPromise> ReadMetadata();
|
||||
|
||||
decltype(mVideoCallback)& VideoCallback() { return mVideoCallback; }
|
||||
decltype(mAudioWaitCallback)& AudioWaitCallback() { return mAudioWaitCallback; }
|
||||
decltype(mVideoWaitCallback)& VideoWaitCallback() { return mVideoWaitCallback; }
|
||||
|
||||
// NOTE: please set callbacks before requesting audio/video data!
|
||||
RefPtr<MediaDataPromise> RequestAudioData();
|
||||
void RequestVideoData(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold);
|
||||
|
||||
RefPtr<MediaDataPromise>
|
||||
RequestVideoData(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold);
|
||||
|
||||
// NOTE: please set callbacks before invoking WaitForData()!
|
||||
void WaitForData(MediaData::Type aType);
|
||||
|
||||
bool IsRequestingVideoData() const;
|
||||
bool IsWaitingAudioData() const;
|
||||
bool IsWaitingVideoData() const;
|
||||
|
||||
|
@ -121,7 +120,6 @@ private:
|
|||
bool mShutdown = false;
|
||||
Maybe<media::TimeUnit> mStartTime;
|
||||
|
||||
MozPromiseRequestHolder<MediaDataPromise> mVideoDataRequest;
|
||||
MozPromiseRequestHolder<WaitForDataPromise> mAudioWaitRequest;
|
||||
MozPromiseRequestHolder<WaitForDataPromise> mVideoWaitRequest;
|
||||
};
|
||||
|
|
|
@ -1072,9 +1072,9 @@ private:
|
|||
void RequestVideoData()
|
||||
{
|
||||
MOZ_ASSERT(!mDoneVideoSeeking);
|
||||
MOZ_ASSERT(!Reader()->IsRequestingVideoData());
|
||||
MOZ_ASSERT(!mMaster->IsRequestingVideoData());
|
||||
MOZ_ASSERT(!Reader()->IsWaitingVideoData());
|
||||
Reader()->RequestVideoData(false, media::TimeUnit());
|
||||
mMaster->RequestVideoData(false, media::TimeUnit());
|
||||
}
|
||||
|
||||
void AdjustFastSeekIfNeeded(MediaData* aSample)
|
||||
|
@ -1280,7 +1280,7 @@ private:
|
|||
|
||||
if (!NeedMoreVideo()) {
|
||||
FinishSeek();
|
||||
} else if (!Reader()->IsRequestingVideoData() &&
|
||||
} else if (!mMaster->IsRequestingVideoData() &&
|
||||
!Reader()->IsWaitingVideoData()) {
|
||||
RequestVideoData();
|
||||
}
|
||||
|
@ -1430,7 +1430,7 @@ private:
|
|||
|
||||
void RequestVideoData()
|
||||
{
|
||||
Reader()->RequestVideoData(false, media::TimeUnit());
|
||||
mMaster->RequestVideoData(false, media::TimeUnit());
|
||||
}
|
||||
|
||||
bool NeedMoreVideo() const
|
||||
|
@ -2141,7 +2141,7 @@ BufferingState::Step()
|
|||
Reader()->IsWaitingAudioData());
|
||||
MOZ_ASSERT(mMaster->mMinimizePreroll ||
|
||||
!mMaster->OutOfDecodedVideo() ||
|
||||
Reader()->IsRequestingVideoData() ||
|
||||
mMaster->IsRequestingVideoData() ||
|
||||
Reader()->IsWaitingVideoData());
|
||||
SLOG("In buffering mode, waiting to be notified: outOfAudio: %d, "
|
||||
"mAudioStatus: %s, outOfVideo: %d, mVideoStatus: %s",
|
||||
|
@ -2188,6 +2188,7 @@ ShutdownState::Enter()
|
|||
// To break the cycle-reference between MediaDecoderReaderWrapper and MDSM.
|
||||
master->CancelMediaDecoderReaderWrapperCallback();
|
||||
master->mAudioDataRequest.DisconnectIfExists();
|
||||
master->mVideoDataRequest.DisconnectIfExists();
|
||||
|
||||
master->Reset();
|
||||
|
||||
|
@ -2579,6 +2580,14 @@ MediaDecoderStateMachine::OnAudioNotDecoded(const MediaResult& aError)
|
|||
OnNotDecoded(MediaData::AUDIO_DATA, aError);
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnVideoNotDecoded(const MediaResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
mVideoDataRequest.Complete();
|
||||
OnNotDecoded(MediaData::VIDEO_DATA, aError);
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType,
|
||||
const MediaResult& aError)
|
||||
|
@ -2595,6 +2604,8 @@ MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideo,
|
|||
MOZ_ASSERT(OnTaskQueue());
|
||||
MOZ_ASSERT(aVideo);
|
||||
|
||||
mVideoDataRequest.Complete();
|
||||
|
||||
// Handle abnormal or negative timestamps.
|
||||
mDecodedVideoEndTime = std::max(mDecodedVideoEndTime, aVideo->GetEndTime());
|
||||
|
||||
|
@ -2705,17 +2716,6 @@ MediaDecoderStateMachine::SetMediaDecoderReaderWrapperCallback()
|
|||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
mVideoCallback = mReader->VideoCallback().Connect(
|
||||
mTaskQueue, [this] (VideoCallbackData aData) {
|
||||
typedef Tuple<MediaData*, TimeStamp> Type;
|
||||
if (aData.is<Type>()) {
|
||||
auto&& v = aData.as<Type>();
|
||||
OnVideoDecoded(Get<0>(v), Get<1>(v));
|
||||
} else {
|
||||
OnNotDecoded(MediaData::VIDEO_DATA, aData.as<MediaResult>());
|
||||
}
|
||||
});
|
||||
|
||||
mAudioWaitCallback = mReader->AudioWaitCallback().Connect(
|
||||
mTaskQueue, [this] (WaitCallbackData aData) {
|
||||
if (aData.is<MediaData::Type>()) {
|
||||
|
@ -2739,7 +2739,6 @@ void
|
|||
MediaDecoderStateMachine::CancelMediaDecoderReaderWrapperCallback()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
mVideoCallback.Disconnect();
|
||||
mAudioWaitCallback.Disconnect();
|
||||
mVideoWaitCallback.Disconnect();
|
||||
}
|
||||
|
@ -3118,33 +3117,35 @@ MediaDecoderStateMachine::EnsureVideoDecodeTaskQueued()
|
|||
}
|
||||
|
||||
if (!IsVideoDecoding() ||
|
||||
mReader->IsRequestingVideoData() ||
|
||||
IsRequestingVideoData() ||
|
||||
mReader->IsWaitingVideoData()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RequestVideoData();
|
||||
RequestVideoData(NeedToSkipToNextKeyframe(),
|
||||
media::TimeUnit::FromMicroseconds(GetMediaTime()));
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::RequestVideoData()
|
||||
MediaDecoderStateMachine::RequestVideoData(bool aSkipToNextKeyframe,
|
||||
const media::TimeUnit& aCurrentTime)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MOZ_ASSERT(mState != DECODER_STATE_SEEKING);
|
||||
|
||||
bool skipToNextKeyFrame = NeedToSkipToNextKeyframe();
|
||||
|
||||
media::TimeUnit currentTime = media::TimeUnit::FromMicroseconds(GetMediaTime());
|
||||
|
||||
SAMPLE_LOG("Queueing video task - queued=%i, decoder-queued=%o, skip=%i, time=%lld",
|
||||
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), skipToNextKeyFrame,
|
||||
currentTime.ToMicroseconds());
|
||||
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), aSkipToNextKeyframe,
|
||||
aCurrentTime.ToMicroseconds());
|
||||
|
||||
// MediaDecoderReaderWrapper::RequestVideoData() records the decoding start
|
||||
// time and sent it back to MDSM::OnVideoDecoded() so that if the decoding is
|
||||
// slow, we can increase our low audio threshold to reduce the chance of an
|
||||
// audio underrun while we're waiting for a video decode to complete.
|
||||
mReader->RequestVideoData(skipToNextKeyFrame, currentTime);
|
||||
TimeStamp videoDecodeStartTime = TimeStamp::Now();
|
||||
mVideoDataRequest.Begin(
|
||||
mReader->RequestVideoData(aSkipToNextKeyframe, aCurrentTime)->Then(
|
||||
OwnerThread(), __func__,
|
||||
[this, videoDecodeStartTime] (MediaData* aVideo) {
|
||||
OnVideoDecoded(aVideo, videoDecodeStartTime);
|
||||
},
|
||||
[this] (const MediaResult& aError) {
|
||||
OnVideoNotDecoded(aError);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3374,6 +3375,7 @@ MediaDecoderStateMachine::Reset(TrackSet aTracks)
|
|||
mDecodedVideoEndTime = 0;
|
||||
mVideoCompleted = false;
|
||||
VideoQueue().Reset();
|
||||
mVideoDataRequest.DisconnectIfExists();
|
||||
}
|
||||
|
||||
if (aTracks.contains(TrackInfo::kAudioTrack)) {
|
||||
|
@ -3796,7 +3798,7 @@ const char*
|
|||
MediaDecoderStateMachine::VideoRequestStatus() const
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
if (mReader->IsRequestingVideoData()) {
|
||||
if (IsRequestingVideoData()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mReader->IsWaitingVideoData());
|
||||
return "pending";
|
||||
} else if (mReader->IsWaitingVideoData()) {
|
||||
|
|
|
@ -330,6 +330,7 @@ private:
|
|||
void OnAudioDecoded(MediaData* aAudio);
|
||||
void OnVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStartTime);
|
||||
void OnAudioNotDecoded(const MediaResult& aError);
|
||||
void OnVideoNotDecoded(const MediaResult& aError);
|
||||
void OnNotDecoded(MediaData::Type aType, const MediaResult& aError);
|
||||
void OnAudioWaited(MediaData::Type aType);
|
||||
void OnVideoWaited(MediaData::Type aType);
|
||||
|
@ -473,9 +474,11 @@ protected:
|
|||
|
||||
// Start a task to decode video.
|
||||
// The decoder monitor must be held.
|
||||
void RequestVideoData();
|
||||
void RequestVideoData(bool aSkipToNextKeyframe,
|
||||
const media::TimeUnit& aCurrentTime);
|
||||
|
||||
bool IsRequestingAudioData() const { return mAudioDataRequest.Exists(); }
|
||||
bool IsRequestingVideoData() const { return mVideoDataRequest.Exists(); }
|
||||
|
||||
// Re-evaluates the state and determines whether we need to dispatch
|
||||
// events to run the decode, or if not whether we should set the reader
|
||||
|
@ -657,12 +660,12 @@ private:
|
|||
// Only one of a given pair of ({Audio,Video}DataPromise, WaitForDataPromise)
|
||||
// should exist at any given moment.
|
||||
|
||||
MediaEventListener mVideoCallback;
|
||||
MediaEventListener mAudioWaitCallback;
|
||||
MediaEventListener mVideoWaitCallback;
|
||||
|
||||
using MediaDataPromise = MediaDecoderReader::MediaDataPromise;
|
||||
MozPromiseRequestHolder<MediaDataPromise> mAudioDataRequest;
|
||||
MozPromiseRequestHolder<MediaDataPromise> mVideoDataRequest;
|
||||
|
||||
const char* AudioRequestStatus() const;
|
||||
const char* VideoRequestStatus() const;
|
||||
|
|
Загрузка…
Ссылка в новой задаче