Bug 1319987: P1. Remove handling for WaitingForKey in MFR. r?cpearce
This is not compatible with promise based decoders. We'll re-implement it in a different fashion later on.
MozReview-Commit-ID: HYBNKVxEUmB
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -1428,31 +1428,16 @@ MediaFormatReader::NotifyWaitingForData(
decoder.mWaitingForData = true;
if (decoder.mTimeThreshold) {
decoder.mTimeThreshold.ref().mWaiting = true;
}
ScheduleUpdate(aTrack);
}
void
-MediaFormatReader::NotifyWaitingForKey(TrackType aTrack)
-{
- MOZ_ASSERT(OnTaskQueue());
- auto& decoder = GetDecoderData(aTrack);
- if (mDecoder) {
- mDecoder->NotifyWaitingForKey();
- }
- if (!decoder.mDecodePending) {
- LOGV("WaitingForKey received while no pending decode. Ignoring");
- }
- decoder.mWaitingForKey = true;
- ScheduleUpdate(aTrack);
-}
-
-void
MediaFormatReader::NotifyEndOfStream(TrackType aTrack)
{
MOZ_ASSERT(OnTaskQueue());
auto& decoder = GetDecoderData(aTrack);
decoder.mDemuxEOS = true;
ScheduleUpdate(aTrack);
}
@@ -1912,20 +1897,16 @@ MediaFormatReader::Update(TrackType aTra
} else if (decoder.mDemuxEOS && !decoder.mNeedDraining &&
!decoder.HasPendingDrain() && decoder.mQueuedSamples.IsEmpty()) {
// It is possible to transition from WAITING_FOR_DATA directly to EOS
// state during the internal seek; in which case no draining would occur.
// There is no more samples left to be decoded and we are already in
// EOS state. We can immediately reject the data promise.
LOG("Rejecting %s promise: EOS", TrackTypeToStr(aTrack));
decoder.RejectPromise(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
- } else if (decoder.mWaitingForKey) {
- LOG("Rejecting %s promise: WAITING_FOR_DATA due to waiting for key",
- TrackTypeToStr(aTrack));
- decoder.RejectPromise(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA, __func__);
}
}
if (decoder.mNeedDraining) {
DrainDecoder(aTrack);
return;
}
@@ -1949,40 +1930,30 @@ MediaFormatReader::Update(TrackType aTra
return;
} else if (aTrack == TrackType::kAudioTrack) {
decoder.Flush();
}
}
bool needInput = NeedInput(decoder);
- LOGV("Update(%s) ni=%d no=%d ie=%d, in:%llu out:%llu qs=%u pending:%u waiting:%d promise:%d wfk:%d sid:%u",
+ LOGV("Update(%s) ni=%d no=%d ie=%d, in:%llu out:%llu qs=%u pending:%u waiting:%d promise:%d sid:%u",
TrackTypeToStr(aTrack), needInput, needOutput, decoder.mDecodePending,
decoder.mNumSamplesInput, decoder.mNumSamplesOutput,
uint32_t(size_t(decoder.mSizeOfQueue)), uint32_t(decoder.mOutput.Length()),
decoder.mWaitingForData, decoder.HasPromise(),
- decoder.mWaitingForKey, decoder.mLastStreamSourceID);
+ decoder.mLastStreamSourceID);
if ((decoder.mWaitingForData &&
- (!decoder.mTimeThreshold || decoder.mTimeThreshold.ref().mWaiting)) ||
- (decoder.mWaitingForKey && decoder.mDecodePending)) {
+ (!decoder.mTimeThreshold || decoder.mTimeThreshold.ref().mWaiting))) {
// Nothing more we can do at present.
LOGV("Still waiting for data or key.");
return;
}
- if (decoder.mWaitingForKey) {
- decoder.mWaitingForKey = false;
- if (decoder.HasWaitingPromise() && !decoder.IsWaiting()) {
- LOGV("No longer waiting for key. Resolving waiting promise");
- decoder.mWaitingPromise.Resolve(decoder.mType, __func__);
- return;
- }
- }
-
if (!needInput) {
LOGV("No need for additional input (pending:%u)",
uint32_t(decoder.mOutput.Length()));
return;
}
// Demux samples if we don't have some.
RequestDemuxSamples(aTrack);
@@ -2144,25 +2115,16 @@ MediaFormatReader::Error(TrackType aTrac
{
RefPtr<nsIRunnable> task =
NewRunnableMethod<TrackType, MediaResult>(
this, &MediaFormatReader::NotifyError, aTrack, aError);
OwnerThread()->Dispatch(task.forget());
}
void
-MediaFormatReader::WaitingForKey(TrackType aTrack)
-{
- RefPtr<nsIRunnable> task =
- NewRunnableMethod<TrackType>(
- this, &MediaFormatReader::NotifyWaitingForKey, aTrack);
- OwnerThread()->Dispatch(task.forget());
-}
-
-void
MediaFormatReader::Reset(TrackType aTrack)
{
MOZ_ASSERT(OnTaskQueue());
LOG("Reset(%s) BEGIN", TrackTypeToStr(aTrack));
auto& decoder = GetDecoderData(aTrack);
decoder.ResetState();
@@ -2672,55 +2634,55 @@ MediaFormatReader::GetMozDebugReaderData
MutexAutoLock mon(mVideo.mMutex);
videoName = mVideo.mDescription;
}
result += nsPrintfCString("audio decoder: %s\n", audioName);
result += nsPrintfCString("audio frames decoded: %lld\n",
mAudio.mNumSamplesOutputTotal);
if (HasAudio()) {
- result += nsPrintfCString("audio state: ni=%d no=%d ie=%d demuxr:%d demuxq:%d tt:%f tths:%d in:%llu out:%llu qs=%u pending:%u waiting:%d wfk:%d sid:%u\n",
+ result += nsPrintfCString("audio state: ni=%d no=%d ie=%d demuxr:%d demuxq:%d tt:%f tths:%d in:%llu out:%llu qs=%u pending:%u waiting:%d sid:%u\n",
NeedInput(mAudio), mAudio.HasPromise(),
mAudio.mDecodePending,
mAudio.mDemuxRequest.Exists(),
int(mAudio.mQueuedSamples.Length()),
mAudio.mTimeThreshold
? mAudio.mTimeThreshold.ref().Time().ToSeconds()
: -1.0,
mAudio.mTimeThreshold
? mAudio.mTimeThreshold.ref().mHasSeeked
: -1,
mAudio.mNumSamplesInput, mAudio.mNumSamplesOutput,
unsigned(size_t(mAudio.mSizeOfQueue)),
unsigned(mAudio.mOutput.Length()),
- mAudio.mWaitingForData, mAudio.mWaitingForKey,
+ mAudio.mWaitingForData,
mAudio.mLastStreamSourceID);
}
result += nsPrintfCString("video decoder: %s\n", videoName);
result += nsPrintfCString("hardware video decoding: %s\n",
VideoIsHardwareAccelerated() ? "enabled" : "disabled");
result += nsPrintfCString("video frames decoded: %lld (skipped:%lld)\n",
mVideo.mNumSamplesOutputTotal,
mVideo.mNumSamplesSkippedTotal);
if (HasVideo()) {
- result += nsPrintfCString("video state: ni=%d no=%d ie=%d demuxr:%d demuxq:%d tt:%f tths:%d in:%llu out:%llu qs=%u pending:%u waiting:%d wfk:%d, sid:%u\n",
+ result += nsPrintfCString("video state: ni=%d no=%d ie=%d demuxr:%d demuxq:%d tt:%f tths:%d in:%llu out:%llu qs=%u pending:%u waiting:%d sid:%u\n",
NeedInput(mVideo), mVideo.HasPromise(),
mVideo.mDecodePending,
mVideo.mDemuxRequest.Exists(),
int(mVideo.mQueuedSamples.Length()),
mVideo.mTimeThreshold
? mVideo.mTimeThreshold.ref().Time().ToSeconds()
: -1.0,
mVideo.mTimeThreshold
? mVideo.mTimeThreshold.ref().mHasSeeked
: -1,
mVideo.mNumSamplesInput, mVideo.mNumSamplesOutput,
unsigned(size_t(mVideo.mSizeOfQueue)),
unsigned(mVideo.mOutput.Length()),
- mVideo.mWaitingForData, mVideo.mWaitingForKey,
+ mVideo.mWaitingForData,
mVideo.mLastStreamSourceID);
}
aString += result;
}
void
MediaFormatReader::SetVideoBlankDecode(bool aIsBlankDecode)
{
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -136,33 +136,31 @@ private:
// Drain the current decoder.
void DrainDecoder(TrackType aTrack);
void NotifyNewOutput(TrackType aTrack, MediaData* aSample);
void NotifyInputExhausted(TrackType aTrack);
void NotifyDrainComplete(TrackType aTrack);
void NotifyError(TrackType aTrack, const MediaResult& aError);
void NotifyWaitingForData(TrackType aTrack);
- void NotifyWaitingForKey(TrackType aTrack);
void NotifyEndOfStream(TrackType aTrack);
void ExtractCryptoInitData(nsTArray<uint8_t>& aInitData);
// Initializes mLayersBackendType if possible.
void InitLayersBackendType();
// DecoderCallback proxies the MediaDataDecoderCallback calls to these
// functions.
void Output(TrackType aType, MediaData* aSample);
void InputExhausted(TrackType aTrack);
void Error(TrackType aTrack, const MediaResult& aError);
void Reset(TrackType aTrack);
void DrainComplete(TrackType aTrack);
void DropDecodedSamples(TrackType aTrack);
- void WaitingForKey(TrackType aTrack);
bool ShouldSkip(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold);
void SetVideoDecodeThreshold();
size_t SizeOfQueue(TrackType aTrack);
RefPtr<PDMFactory> mPlatform;
@@ -187,37 +185,32 @@ private:
mReader->DrainComplete(mType);
}
void ReleaseMediaResources() override {
mReader->ReleaseResources();
}
bool OnReaderTaskQueue() override {
return mReader->OnTaskQueue();
}
- void WaitingForKey() override {
- mReader->WaitingForKey(mType);
- }
-
private:
MediaFormatReader* mReader;
TrackType mType;
};
struct DecoderData {
DecoderData(MediaFormatReader* aOwner,
MediaData::Type aType,
uint32_t aNumOfMaxError)
: mOwner(aOwner)
, mType(aType)
, mMutex("DecoderData")
, mDescription("shutdown")
, mUpdateScheduled(false)
, mDemuxEOS(false)
, mWaitingForData(false)
- , mWaitingForKey(false)
, mReceivedNewData(false)
, mOutputRequested(false)
, mDecodePending(false)
, mNeedDraining(false)
, mDraining(false)
, mDrainComplete(false)
, mNumOfConsecutiveError(0)
, mMaxConsecutiveError(aNumOfMaxError)
@@ -255,17 +248,16 @@ private:
mDescription = "shutdown";
mDecoder = nullptr;
}
// Only accessed from reader's task queue.
bool mUpdateScheduled;
bool mDemuxEOS;
bool mWaitingForData;
- bool mWaitingForKey;
bool mReceivedNewData;
// Pending seek.
MozPromiseRequestHolder<MediaTrackDemuxer::SeekPromise> mSeekRequest;
// Queued demux samples waiting to be decoded.
nsTArray<RefPtr<MediaRawData>> mQueuedSamples;
MozPromiseRequestHolder<MediaTrackDemuxer::SamplesPromise> mDemuxRequest;
@@ -275,17 +267,17 @@ private:
bool HasWaitingPromise() const
{
MOZ_ASSERT(mOwner->OnTaskQueue());
return !mWaitingPromise.IsEmpty();
}
bool IsWaiting() const
{
MOZ_ASSERT(mOwner->OnTaskQueue());
- return mWaitingForData || mWaitingForKey;
+ return mWaitingForData;
}
// MediaDataDecoder handler's variables.
bool mOutputRequested;
// Set to true once the MediaDataDecoder has been fed a compressed sample.
// No more samples will be passed to the decoder while true.
// mDecodePending is reset when:
// 1- The decoder calls InputExhausted
@@ -378,17 +370,16 @@ private:
// (pending demuxed and decoded).
// Decoding will be suspended until mInputRequested is set again.
// The track demuxer is *not* reset.
void ResetState()
{
MOZ_ASSERT(mOwner->OnTaskQueue());
mDemuxEOS = false;
mWaitingForData = false;
- mWaitingForKey = false;
mQueuedSamples.Clear();
mOutputRequested = false;
mNeedDraining = false;
mDecodePending = false;
mDraining = false;
mDrainComplete = false;
mTimeThreshold.reset();
mLastSampleTime.reset();
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -201,22 +201,16 @@ public:
// been called.
virtual void InputExhausted() = 0;
virtual void DrainComplete() = 0;
virtual void ReleaseMediaResources() {}
virtual bool OnReaderTaskQueue() = 0;
-
- // Denotes that a pending encryption key is preventing more input being fed
- // into the decoder. This only needs to be overridden for callbacks that
- // handle encryption. E.g. benchmarking does not use eme, so this need
- // not be overridden in that case.
- virtual void WaitingForKey() {}
};
// MediaDataDecoder is the interface exposed by decoders created by the
// PlatformDecoderModule's Create*Decoder() functions. The type of
// media data that the decoder accepts as valid input and produces as
// output is determined when the MediaDataDecoder is created.
//
// Unless otherwise noted, all functions are only called on the decode task
--- a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
+++ b/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
@@ -35,17 +35,16 @@ SamplesWaitingForKey::WaitIfKeyNotUsable
}
CDMCaps::AutoLock caps(mProxy->Capabilites());
const auto& keyid = aSample->mCrypto.mKeyId;
if (!caps.IsKeyUsable(keyid)) {
{
MutexAutoLock lock(mMutex);
mSamples.AppendElement(aSample);
}
- mDecoderCallback->WaitingForKey();
caps.NotifyWhenKeyIdUsable(aSample->mCrypto.mKeyId, this);
return true;
}
return false;
}
void
SamplesWaitingForKey::NotifyUsable(const CencKeyId& aKeyId)
--- a/dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.h
+++ b/dom/media/platforms/agnostic/gmp/MediaDataDecoderProxy.h
@@ -90,21 +90,16 @@ public:
void FlushComplete();
bool OnReaderTaskQueue() override
{
return mProxyCallback->OnReaderTaskQueue();
}
- void WaitingForKey() override
- {
- mProxyCallback->WaitingForKey();
- }
-
private:
MediaDataDecoderProxy* mProxyDecoder;
MediaDataDecoderCallback* mProxyCallback;
};
class MediaDataDecoderProxy : public MediaDataDecoder {
public:
MediaDataDecoderProxy(already_AddRefed<AbstractThread> aProxyThread,