diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp index 6c65699e638d..f7d06bfcc844 100644 --- a/dom/media/MediaFormatReader.cpp +++ b/dom/media/MediaFormatReader.cpp @@ -96,8 +96,7 @@ MediaFormatReader::Shutdown() mAudio.RejectPromise(CANCELED, __func__); } mAudio.mInitPromise.DisconnectIfExists(); - mAudio.mDecoder->Shutdown(); - mAudio.mDecoder = nullptr; + mAudio.ShutdownDecoder(); } if (mAudio.mTrackDemuxer) { mAudio.ResetDemuxer(); @@ -117,8 +116,7 @@ MediaFormatReader::Shutdown() mVideo.RejectPromise(CANCELED, __func__); } mVideo.mInitPromise.DisconnectIfExists(); - mVideo.mDecoder->Shutdown(); - mVideo.mDecoder = nullptr; + mVideo.ShutdownDecoder(); } if (mVideo.mTrackDemuxer) { mVideo.ResetDemuxer(); @@ -381,6 +379,8 @@ MediaFormatReader::EnsureDecoderCreated(TrackType aTrack) decoder.mDecoderInitialized = false; + MonitorAutoLock mon(decoder.mMonitor); + switch (aTrack) { case TrackType::kAudioTrack: decoder.mDecoder = @@ -406,6 +406,11 @@ MediaFormatReader::EnsureDecoderCreated(TrackType aTrack) default: break; } + if (decoder.mDecoder ) { + decoder.mDescription = decoder.mDecoder->GetDescriptionName(); + } else { + decoder.mDescription = "error creating decoder"; + } return decoder.mDecoder != nullptr; } @@ -429,13 +434,14 @@ MediaFormatReader::EnsureDecoderInitialized(TrackType aTrack) auto& decoder = self->GetDecoderData(aTrack); decoder.mInitPromise.Complete(); decoder.mDecoderInitialized = true; + MonitorAutoLock mon(decoder.mMonitor); + decoder.mDescription = decoder.mDecoder->GetDescriptionName(); self->ScheduleUpdate(aTrack); }, [self, aTrack] (MediaDataDecoder::DecoderFailureReason aResult) { auto& decoder = self->GetDecoderData(aTrack); decoder.mInitPromise.Complete(); - decoder.mDecoder->Shutdown(); - decoder.mDecoder = nullptr; + decoder.ShutdownDecoder(); self->NotifyError(aTrack); })); return false; @@ -465,8 +471,7 @@ MediaFormatReader::DisableHardwareAcceleration() if (HasVideo() && !mHardwareAccelerationDisabled) { mHardwareAccelerationDisabled = true; Flush(TrackInfo::kVideoTrack); - mVideo.mDecoder->Shutdown(); - mVideo.mDecoder = nullptr; + mVideo.ShutdownDecoder(); if (!EnsureDecoderCreated(TrackType::kVideoTrack)) { LOG("Unable to re-create decoder, aborting"); NotifyError(TrackInfo::kVideoTrack); @@ -919,8 +924,7 @@ MediaFormatReader::HandleDemuxedSamples(TrackType aTrack, // Flush will clear our array of queued samples. So make a copy now. nsTArray> samples{decoder.mQueuedSamples}; Flush(aTrack); - decoder.mDecoder->Shutdown(); - decoder.mDecoder = nullptr; + decoder.ShutdownDecoder(); if (sample->mKeyframe) { decoder.mQueuedSamples.AppendElements(Move(samples)); NotifyDecodingRequested(aTrack); @@ -1604,11 +1608,8 @@ void MediaFormatReader::ReleaseMediaResources() if (mVideoFrameContainer) { mVideoFrameContainer->ClearCurrentFrame(); } - if (mVideo.mDecoder) { - mVideo.mInitPromise.DisconnectIfExists(); - mVideo.mDecoder->Shutdown(); - mVideo.mDecoder = nullptr; - } + mVideo.mInitPromise.DisconnectIfExists(); + mVideo.ShutdownDecoder(); } bool @@ -1666,12 +1667,25 @@ void MediaFormatReader::GetMozDebugReaderData(nsAString& aString) { nsAutoCString result; + const char* audioName = "unavailable"; + const char* videoName = audioName; + + if (HasAudio()) { + MonitorAutoLock mon(mAudio.mMonitor); + audioName = mAudio.mDescription; + } + if (HasVideo()) { + MonitorAutoLock mon(mVideo.mMonitor); + videoName = mVideo.mDescription; + } + + result += nsPrintfCString("audio decoder: %s\n", audioName); + result += nsPrintfCString("audio frames decoded: %lld\n", + mAudio.mNumSamplesOutputTotal); + result += nsPrintfCString("video decoder: %s\n", videoName); result += nsPrintfCString("hardware video decoding: %s\n", VideoIsHardwareAccelerated() ? "enabled" : "disabled"); - result += nsPrintfCString("audio frames decoded: %lld (skipped:%lld)\n" - "video frames decoded: %lld (skipped:%lld)\n", - mAudio.mNumSamplesOutputTotal, - mAudio.mNumSamplesSkippedTotal, + result += nsPrintfCString("video frames decoded: %lld (skipped:%lld)\n", mVideo.mNumSamplesOutputTotal, mVideo.mNumSamplesSkippedTotal); aString += NS_ConvertUTF8toUTF16(result); diff --git a/dom/media/MediaFormatReader.h b/dom/media/MediaFormatReader.h index 30207b59fc4e..4fe53ed24be3 100644 --- a/dom/media/MediaFormatReader.h +++ b/dom/media/MediaFormatReader.h @@ -10,6 +10,7 @@ #include "mozilla/Atomics.h" #include "mozilla/Maybe.h" #include "mozilla/TaskQueue.h" +#include "mozilla/Monitor.h" #include "MediaDataDemuxer.h" #include "MediaDecoderReader.h" @@ -213,6 +214,8 @@ private: uint32_t aDecodeAhead) : mOwner(aOwner) , mType(aType) + , mMonitor("DecoderData") + , mDescription("shutdown") , mDecodeAhead(aDecodeAhead) , mUpdateScheduled(false) , mDemuxEOS(false) @@ -240,14 +243,27 @@ private: // Disambiguate Audio vs Video. MediaData::Type mType; RefPtr mTrackDemuxer; - // The platform decoder. - RefPtr mDecoder; // TaskQueue on which decoder can choose to decode. // Only non-null up until the decoder is created. RefPtr mTaskQueue; // Callback that receives output and error notifications from the decoder. nsAutoPtr mCallback; + // Monitor protecting mDescription and mDecoder. + Monitor mMonitor; + // The platform decoder. + RefPtr mDecoder; + const char* mDescription; + void ShutdownDecoder() + { + MonitorAutoLock mon(mMonitor); + if (mDecoder) { + mDecoder->Shutdown(); + } + mDescription = "shutdown"; + mDecoder = nullptr; + } + // Only accessed from reader's task queue. uint32_t mDecodeAhead; bool mUpdateScheduled;