tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaChangeMonitor.h (6858B)


      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 "PDMFactory.h"
     11 #include "PlatformDecoderModule.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 final
     28    : public MediaDataDecoder,
     29      public DecoderDoctorLifeLogger<MediaChangeMonitor> {
     30 public:
     31  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaChangeMonitor, final);
     32 
     33  static RefPtr<PlatformDecoderModule::CreateDecoderPromise> Create(
     34      PDMFactory* aPDMFactory, const CreateDecoderParams& aParams);
     35 
     36  RefPtr<InitPromise> Init() override;
     37  RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
     38  RefPtr<DecodePromise> Drain() override;
     39  RefPtr<FlushPromise> Flush() override;
     40  RefPtr<ShutdownPromise> Shutdown() override;
     41  bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
     42  nsCString GetDescriptionName() const override {
     43    if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
     44      return decoder->GetDescriptionName();
     45    }
     46    return "MediaChangeMonitor decoder (pending)"_ns;
     47  }
     48  nsCString GetProcessName() const override {
     49    if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
     50      return decoder->GetProcessName();
     51    }
     52    return "MediaChangeMonitor"_ns;
     53  }
     54  nsCString GetCodecName() const override {
     55    if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
     56      return decoder->GetCodecName();
     57    }
     58    return "MediaChangeMonitor"_ns;
     59  }
     60  void SetSeekThreshold(const media::TimeUnit& aTime) override;
     61  bool SupportDecoderRecycling() const override {
     62    if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
     63      return decoder->SupportDecoderRecycling();
     64    }
     65    return false;
     66  }
     67  bool ShouldDecoderAlwaysBeRecycled() const override {
     68    if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
     69      return decoder->ShouldDecoderAlwaysBeRecycled();
     70    }
     71    return false;
     72  }
     73 
     74  ConversionRequired NeedsConversion() const override {
     75    if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
     76      return decoder->NeedsConversion();
     77    }
     78    // Default so no conversion is performed.
     79    return ConversionRequired::kNeedNone;
     80  }
     81 
     82  Maybe<PropertyValue> GetDecodeProperty(PropertyName aName) const override {
     83    if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) {
     84      return decoder->GetDecodeProperty(aName);
     85    }
     86    return MediaDataDecoder::GetDecodeProperty(aName);
     87  }
     88 
     89  class CodecChangeMonitor {
     90   public:
     91    virtual bool CanBeInstantiated() const = 0;
     92    virtual MediaResult CheckForChange(MediaRawData* aSample) = 0;
     93    virtual const TrackInfo& Config() const = 0;
     94    virtual MediaResult PrepareSample(
     95        MediaDataDecoder::ConversionRequired aConversion, MediaRawData* aSample,
     96        bool aNeedKeyFrame) = 0;
     97    virtual bool IsHardwareAccelerated(nsACString& aFailureReason) const {
     98      return false;
     99    }
    100    virtual void Flush() {};
    101    virtual ~CodecChangeMonitor() = default;
    102  };
    103 
    104 private:
    105  MediaChangeMonitor(PDMFactory* aPDMFactory,
    106                     UniquePtr<CodecChangeMonitor>&& aCodecChangeMonitor,
    107                     MediaDataDecoder* aDecoder,
    108                     const CreateDecoderParams& aParams);
    109  virtual ~MediaChangeMonitor();
    110 
    111  void AssertOnThread() const {
    112    // mThread may not be set if Init hasn't been called first.
    113    MOZ_ASSERT(!mThread || mThread->IsOnCurrentThread());
    114  }
    115 
    116  // This is used for getting decoder debug info on other threads. Thread-safe.
    117  MediaDataDecoder* GetDecoderOnNonOwnerThread() const;
    118 
    119  bool CanRecycleDecoder() const;
    120 
    121  typedef MozPromise<bool, MediaResult, true /* exclusive */>
    122      CreateDecoderPromise;
    123  // Will create the required MediaDataDecoder if need AVCC and we have a SPS
    124  // NAL. Returns NS_ERROR_FAILURE if error is permanent and can't be recovered
    125  // and will set mError accordingly.
    126  RefPtr<CreateDecoderPromise> CreateDecoder();
    127  MediaResult CreateDecoderAndInit(MediaRawData* aSample);
    128  MediaResult CheckForChange(MediaRawData* aSample);
    129 
    130  void DecodeFirstSample(MediaRawData* aSample);
    131  void DrainThenFlushDecoder(MediaRawData* aPendingSample);
    132  void FlushThenShutdownDecoder(MediaRawData* aPendingSample);
    133  RefPtr<ShutdownPromise> ShutdownDecoder();
    134 
    135  UniquePtr<CodecChangeMonitor> mChangeMonitor;
    136  RefPtr<PDMFactory> mPDMFactory;
    137  UniquePtr<TrackInfo> mCurrentConfig;
    138  nsCOMPtr<nsISerialEventTarget> mThread;
    139  RefPtr<MediaDataDecoder> mDecoder;
    140  MozPromiseRequestHolder<CreateDecoderPromise> mDecoderRequest;
    141  MozPromiseRequestHolder<InitPromise> mInitPromiseRequest;
    142  MozPromiseHolder<InitPromise> mInitPromise;
    143  MozPromiseRequestHolder<DecodePromise> mDecodePromiseRequest;
    144  MozPromiseHolder<DecodePromise> mDecodePromise;
    145  MozPromiseRequestHolder<FlushPromise> mFlushRequest;
    146  MediaDataDecoder::DecodedData mPendingFrames;
    147  MozPromiseRequestHolder<DecodePromise> mDrainRequest;
    148  MozPromiseRequestHolder<ShutdownPromise> mShutdownRequest;
    149  RefPtr<ShutdownPromise> mShutdownPromise;
    150  MozPromiseHolder<FlushPromise> mFlushPromise;
    151 
    152  bool mNeedKeyframe = true;
    153  Maybe<bool> mCanRecycleDecoder;
    154  Maybe<MediaDataDecoder::ConversionRequired> mConversionRequired;
    155  bool mDecoderInitialized = false;
    156  const CreateDecoderParamsForAsync mParams;
    157  // Keep any seek threshold set for after decoder creation and initialization.
    158  Maybe<media::TimeUnit> mPendingSeekThreshold;
    159 
    160  // This lock is used for mDecoder specifically, but it doens't need to be used
    161  // for every places accessing mDecoder which is mostly on the owner thread.
    162  // However, when requesting decoder debug info, it can happen on other
    163  // threads, so we need this mutex to avoid the data race of
    164  // creating/destroying decoder and accessing decoder's debug info.
    165  mutable Mutex MOZ_ANNOTATED mMutex{"MediaChangeMonitor"};
    166 };
    167 
    168 }  // namespace mozilla
    169 
    170 #endif  // mozilla_H264Converter_h