Bug 1274626 part 5 - provide APIs to switch to blank decoders dynamically; r=jya
MozReview-Commit-ID: PyoIsrEf1r
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -312,16 +312,21 @@ public:
MOZ_ASSERT(OnTaskQueue());
mIsSuspended = aState;
}
AbstractCanonical<bool>* CanonicalIsSuspended() {
return &mIsSuspended;
}
+ // Switch the video decoder to BlankDecoderModule. It might takes effective
+ // since a few samples later depends on how much demuxed samples are already
+ // queued in the original video decoder.
+ virtual void SetVideoBlankDecode(bool aIsBlankDecode) {}
+
protected:
virtual ~MediaDecoderReader();
// Populates aBuffered with the time ranges which are buffered. This may only
// be called on the decode task queue, and should only be used internally by
// UpdateBuffered - mBuffered (or mirrors of it) should be used for everything
// else.
//
--- a/dom/media/MediaDecoderReaderWrapper.cpp
+++ b/dom/media/MediaDecoderReaderWrapper.cpp
@@ -405,9 +405,19 @@ MediaDecoderReaderWrapper::OnMetadataRea
self->mReader->DispatchSetStartTime(self->StartTime().ToMicroseconds());
},
[] () {
NS_WARNING("Setting start time on reader failed");
});
}
}
+void
+MediaDecoderReaderWrapper::SetVideoBlankDecode(bool aIsBlankDecode)
+{
+ MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
+ nsCOMPtr<nsIRunnable> r =
+ NewRunnableMethod<bool>(mReader, &MediaDecoderReader::SetVideoBlankDecode,
+ aIsBlankDecode);
+ mReader->OwnerThread()->Dispatch(r.forget());
+}
+
} // namespace mozilla
--- a/dom/media/MediaDecoderReaderWrapper.h
+++ b/dom/media/MediaDecoderReaderWrapper.h
@@ -116,16 +116,18 @@ public:
AbstractCanonical<bool>* CanonicalIsSuspended() {
return mReader->CanonicalIsSuspended();
}
#ifdef MOZ_EME
void SetCDMProxy(CDMProxy* aProxy) { mReader->SetCDMProxy(aProxy); }
#endif
+ void SetVideoBlankDecode(bool aIsBlankDecode);
+
private:
~MediaDecoderReaderWrapper();
void OnMetadataRead(MetadataHolder* aMetadata);
void OnMetadataNotRead() {}
MediaCallbackExc<WaitCallbackData>& WaitCallbackRef(MediaData::Type aType);
MozPromiseRequestHolder<WaitForDataPromise>& WaitRequestRef(MediaData::Type aType);
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -413,31 +413,33 @@ MediaFormatReader::EnsureDecoderCreated(
MonitorAutoLock mon(decoder.mMonitor);
switch (aTrack) {
case TrackType::kAudioTrack: {
decoder.mDecoder = mPlatform->CreateDecoder({
decoder.mInfo ? *decoder.mInfo->GetAsAudioInfo() : mInfo.mAudio,
decoder.mTaskQueue,
decoder.mCallback.get(),
- mCrashHelper
+ mCrashHelper,
+ decoder.mIsBlankDecode
});
break;
}
case TrackType::kVideoTrack: {
// Decoders use the layers backend to decide if they can use hardware decoding,
// so specify LAYERS_NONE if we want to forcibly disable it.
decoder.mDecoder = mPlatform->CreateDecoder({
mVideo.mInfo ? *mVideo.mInfo->GetAsVideoInfo() : mInfo.mVideo,
decoder.mTaskQueue,
decoder.mCallback.get(),
mLayersBackendType,
GetImageContainer(),
- mCrashHelper
+ mCrashHelper,
+ decoder.mIsBlankDecode
});
break;
}
default:
break;
}
if (decoder.mDecoder ) {
decoder.mDescription = decoder.mDecoder->GetDescriptionName();
@@ -2051,9 +2053,37 @@ MediaFormatReader::GetMozDebugReaderData
mVideo.mNumSamplesInput, mVideo.mNumSamplesOutput,
unsigned(size_t(mVideo.mSizeOfQueue)),
unsigned(mVideo.mOutput.Length()),
mVideo.mWaitingForData, mVideo.mLastStreamSourceID);
}
aString += NS_ConvertUTF8toUTF16(result);
}
+void
+MediaFormatReader::SetVideoBlankDecode(bool aIsBlankDecode)
+{
+ MOZ_ASSERT(OnTaskQueue());
+ return SetBlankDecode(TrackType::kVideoTrack, aIsBlankDecode);
+}
+
+void
+MediaFormatReader::SetBlankDecode(TrackType aTrack, bool aIsBlankDecode)
+{
+ MOZ_ASSERT(OnTaskQueue());
+ auto& decoder = GetDecoderData(aTrack);
+
+ LOG("%s, decoder.mIsBlankDecode = %d => aIsBlankDecode = %d",
+ TrackTypeToStr(aTrack), decoder.mIsBlankDecode, aIsBlankDecode);
+
+ if (decoder.mIsBlankDecode == aIsBlankDecode) {
+ return;
+ }
+
+ decoder.mIsBlankDecode = aIsBlankDecode;
+ decoder.Flush();
+ decoder.ShutdownDecoder();
+ NotifyDecodingRequested(TrackInfo::kVideoTrack); // Calls ScheduleUpdate().
+
+ return;
+}
+
} // namespace mozilla
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -96,16 +96,18 @@ public:
#ifdef MOZ_EME
void SetCDMProxy(CDMProxy* aProxy) override;
#endif
// Returns a string describing the state of the decoder data.
// Used for debugging purposes.
void GetMozDebugReaderData(nsAString& aString);
+ void SetVideoBlankDecode(bool aIsBlankDecode) override;
+
private:
bool HasVideo() { return mVideo.mTrackDemuxer; }
bool HasAudio() { return mAudio.mTrackDemuxer; }
bool IsWaitingOnCDMResource();
bool InitDemuxer();
@@ -248,16 +250,17 @@ private:
, mMaxConsecutiveError(aNumOfMaxError)
, mNumSamplesInput(0)
, mNumSamplesOutput(0)
, mNumSamplesOutputTotal(0)
, mNumSamplesSkippedTotal(0)
, mSizeOfQueue(0)
, mIsHardwareAccelerated(false)
, mLastStreamSourceID(UINT32_MAX)
+ , mIsBlankDecode(false)
{}
MediaFormatReader* mOwner;
// Disambiguate Audio vs Video.
MediaData::Type mType;
RefPtr<MediaTrackDemuxer> mTrackDemuxer;
// TaskQueue on which decoder can choose to decode.
// Only non-null up until the decoder is created.
@@ -422,16 +425,19 @@ private:
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;
+ // Use BlankDecoderModule or not.
+ bool mIsBlankDecode;
+
};
class DecoderDataWithPromise : public DecoderData {
public:
DecoderDataWithPromise(MediaFormatReader* aOwner,
MediaData::Type aType,
uint32_t aDecodeAhead,
uint32_t aNumOfMaxError)
@@ -566,13 +572,15 @@ private:
RefPtr<VideoFrameContainer> mVideoFrameContainer;
layers::ImageContainer* GetImageContainer();
#ifdef MOZ_EME
RefPtr<CDMProxy> mCDMProxy;
#endif
RefPtr<GMPCrashHelper> mCrashHelper;
+
+ void SetBlankDecode(TrackType aTrack, bool aIsBlankDecode);
};
} // namespace mozilla
#endif