1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_H264Converter_h 8 #define mozilla_H264Converter_h 9 10 #include "PlatformDecoderModule.h" 11 #include "mozilla/Atomics.h" 12 #include "mozilla/Maybe.h" 13 #include "mozilla/UniquePtr.h" 14 15 namespace mozilla { 16 17 DDLoggedTypeDeclNameAndBase(MediaChangeMonitor, MediaDataDecoder); 18 19 // MediaChangeMonitor is a MediaDataDecoder wrapper used to ensure that 20 // only one type of content is fed to the underlying MediaDataDecoder. 21 // The MediaChangeMonitor allows playback of content where some out of band 22 // extra data (such as SPS NAL for H264 content) may not be provided in the 23 // init segment (e.g. AVC3 or Annex B) MediaChangeMonitor will monitor the 24 // input data, and will delay creation of the MediaDataDecoder until such out 25 // of band have been extracted should the underlying decoder required it. 26 27 class MediaChangeMonitor : public MediaDataDecoder, 28 public DecoderDoctorLifeLogger<MediaChangeMonitor> { 29 public: 30 static RefPtr<PlatformDecoderModule::CreateDecoderPromise> Create( 31 PlatformDecoderModule* aPDM, const CreateDecoderParams& aParams); 32 33 RefPtr<InitPromise> Init() override; 34 RefPtr<DecodePromise> Decode(MediaRawData* aSample) override; 35 RefPtr<DecodePromise> Drain() override; 36 RefPtr<FlushPromise> Flush() override; 37 RefPtr<ShutdownPromise> Shutdown() override; 38 bool IsHardwareAccelerated(nsACString& aFailureReason) const override; GetDescriptionName()39 nsCString GetDescriptionName() const override { 40 if (mDecoder) { 41 return mDecoder->GetDescriptionName(); 42 } 43 return "MediaChangeMonitor decoder (pending)"_ns; 44 } 45 void SetSeekThreshold(const media::TimeUnit& aTime) override; SupportDecoderRecycling()46 bool SupportDecoderRecycling() const override { 47 if (mDecoder) { 48 return mDecoder->SupportDecoderRecycling(); 49 } 50 return false; 51 } 52 NeedsConversion()53 ConversionRequired NeedsConversion() const override { 54 if (mDecoder) { 55 return mDecoder->NeedsConversion(); 56 } 57 // Default so no conversion is performed. 58 return ConversionRequired::kNeedNone; 59 } 60 61 class CodecChangeMonitor { 62 public: 63 virtual bool CanBeInstantiated() const = 0; 64 virtual MediaResult CheckForChange(MediaRawData* aSample) = 0; 65 virtual const TrackInfo& Config() const = 0; 66 virtual MediaResult PrepareSample( 67 MediaDataDecoder::ConversionRequired aConversion, MediaRawData* aSample, 68 bool aNeedKeyFrame) = 0; 69 virtual ~CodecChangeMonitor() = default; 70 }; 71 72 private: 73 MediaChangeMonitor(PlatformDecoderModule* aPDM, 74 UniquePtr<CodecChangeMonitor>&& aCodecChangeMonitor, 75 MediaDataDecoder* aDecoder, 76 const CreateDecoderParams& aParams); 77 virtual ~MediaChangeMonitor(); 78 AssertOnThread()79 void AssertOnThread() const { 80 // mThread may not be set if Init hasn't been called first. 81 MOZ_ASSERT(!mThread || mThread->IsOnCurrentThread()); 82 } 83 84 bool CanRecycleDecoder() const; 85 86 typedef MozPromise<bool, MediaResult, true /* exclusive */> 87 CreateDecoderPromise; 88 // Will create the required MediaDataDecoder if need AVCC and we have a SPS 89 // NAL. Returns NS_ERROR_FAILURE if error is permanent and can't be recovered 90 // and will set mError accordingly. 91 RefPtr<CreateDecoderPromise> CreateDecoder(); 92 MediaResult CreateDecoderAndInit(MediaRawData* aSample); 93 MediaResult CheckForChange(MediaRawData* aSample); 94 95 void DecodeFirstSample(MediaRawData* aSample); 96 void DrainThenFlushDecoder(MediaRawData* aPendingSample); 97 void FlushThenShutdownDecoder(MediaRawData* aPendingSample); 98 RefPtr<ShutdownPromise> ShutdownDecoder(); 99 100 UniquePtr<CodecChangeMonitor> mChangeMonitor; 101 RefPtr<PlatformDecoderModule> mPDM; 102 VideoInfo mCurrentConfig; 103 nsCOMPtr<nsISerialEventTarget> mThread; 104 RefPtr<MediaDataDecoder> mDecoder; 105 MozPromiseRequestHolder<CreateDecoderPromise> mDecoderRequest; 106 MozPromiseRequestHolder<InitPromise> mInitPromiseRequest; 107 MozPromiseHolder<InitPromise> mInitPromise; 108 MozPromiseRequestHolder<DecodePromise> mDecodePromiseRequest; 109 MozPromiseHolder<DecodePromise> mDecodePromise; 110 MozPromiseRequestHolder<FlushPromise> mFlushRequest; 111 MediaDataDecoder::DecodedData mPendingFrames; 112 MozPromiseRequestHolder<DecodePromise> mDrainRequest; 113 MozPromiseRequestHolder<ShutdownPromise> mShutdownRequest; 114 RefPtr<ShutdownPromise> mShutdownPromise; 115 MozPromiseHolder<FlushPromise> mFlushPromise; 116 117 bool mNeedKeyframe = true; 118 Maybe<bool> mCanRecycleDecoder; 119 Maybe<MediaDataDecoder::ConversionRequired> mConversionRequired; 120 bool mDecoderInitialized = false; 121 const CreateDecoderParamsForAsync mParams; 122 }; 123 124 } // namespace mozilla 125 126 #endif // mozilla_H264Converter_h 127