tor-browser

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

MFMediaEngineStream.h (8404B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef DOM_MEDIA_PLATFORM_WMF_MFMEDIAENGINESTREAM_H
      6 #define DOM_MEDIA_PLATFORM_WMF_MFMEDIAENGINESTREAM_H
      7 
      8 #include <mfidl.h>
      9 #include <wrl.h>
     10 
     11 #include <queue>
     12 
     13 #include "BlankDecoderModule.h"
     14 #include "MediaQueue.h"
     15 #include "PlatformDecoderModule.h"
     16 #include "mozilla/Atomics.h"
     17 #include "mozilla/Mutex.h"
     18 
     19 namespace mozilla {
     20 
     21 class MFMediaEngineVideoStream;
     22 class MFMediaSource;
     23 
     24 /**
     25 * MFMediaEngineStream represents a track which would be responsible to provide
     26 * encoded data into the media engine. The media engine can access this stream
     27 * by the presentation descriptor which was acquired from the custom media
     28 * source.
     29 */
     30 class MFMediaEngineStream
     31    : public Microsoft::WRL::RuntimeClass<
     32          Microsoft::WRL::RuntimeClassFlags<
     33              Microsoft::WRL::RuntimeClassType::ClassicCom>,
     34          IMFMediaStream> {
     35 public:
     36  MFMediaEngineStream();
     37  ~MFMediaEngineStream();
     38 
     39  virtual nsCString GetDescriptionName() const = 0;
     40 
     41  virtual nsCString GetCodecName() const = 0;
     42 
     43  HRESULT RuntimeClassInitialize(uint64_t aStreamId, const TrackInfo& aInfo,
     44                                 bool aIsEncryptedCustomInit,
     45                                 MFMediaSource* aParentSource);
     46 
     47  // Called by MFMediaSource.
     48  HRESULT Start(const PROPVARIANT* aPosition);
     49  HRESULT Seek(const PROPVARIANT* aPosition);
     50  HRESULT Stop();
     51  HRESULT Pause();
     52  void Shutdown();
     53 
     54  void SetSelected(bool aSelected);
     55  bool IsSelected() const { return mIsSelected; }
     56  DWORD DescriptorId() const { return mStreamDescriptorId; }
     57 
     58  // Methods for IMFMediaStream
     59  IFACEMETHODIMP GetMediaSource(IMFMediaSource** aMediaSource) override;
     60  IFACEMETHODIMP GetStreamDescriptor(
     61      IMFStreamDescriptor** aStreamDescriptor) override;
     62  IFACEMETHODIMP RequestSample(IUnknown* aToken) override;
     63 
     64  // Methods for IMFMediaEventGenerator, IMFMediaStream derives from
     65  // IMFMediaEventGenerator.
     66  IFACEMETHODIMP GetEvent(DWORD aFlags, IMFMediaEvent** aEvent) override;
     67  IFACEMETHODIMP BeginGetEvent(IMFAsyncCallback* aCallback,
     68                               IUnknown* aState) override;
     69  IFACEMETHODIMP EndGetEvent(IMFAsyncResult* aResult,
     70                             IMFMediaEvent** aEvent) override;
     71  IFACEMETHODIMP QueueEvent(MediaEventType aType, REFGUID aExtendedType,
     72                            HRESULT aStatus,
     73                            const PROPVARIANT* aValue) override;
     74 
     75  TaskQueue* GetTaskQueue() { return mTaskQueue; }
     76 
     77  void NotifyEndOfStream() {
     78    Microsoft::WRL::ComPtr<MFMediaEngineStream> self = this;
     79    (void)mTaskQueue->Dispatch(NS_NewRunnableFunction(
     80        "MFMediaEngineStream::NotifyEndOfStream",
     81        [self]() { self->NotifyEndOfStreamInternal(); }));
     82  }
     83 
     84  // Return the type of the track, the result should be either audio or video.
     85  virtual TrackInfo::TrackType TrackType() = 0;
     86 
     87  virtual RefPtr<MediaDataDecoder::FlushPromise> Flush();
     88 
     89  MediaEventProducer<TrackInfo::TrackType>& EndedEvent() { return mEndedEvent; }
     90 
     91  // True if the stream has been shutdown, it's a thread safe method.
     92  bool IsShutdown() const { return mIsShutdown; }
     93 
     94  virtual MFMediaEngineVideoStream* AsVideoStream() { return nullptr; }
     95 
     96  virtual RefPtr<MediaDataDecoder::DecodePromise> OutputData(
     97      RefPtr<MediaRawData> aSample);
     98 
     99  virtual RefPtr<MediaDataDecoder::DecodePromise> Drain();
    100 
    101  virtual MediaDataDecoder::ConversionRequired NeedsConversion() const {
    102    return MediaDataDecoder::ConversionRequired::kNeedNone;
    103  }
    104 
    105  virtual bool IsEncrypted() const = 0;
    106 
    107 protected:
    108  HRESULT GenerateStreamDescriptor(
    109      Microsoft::WRL::ComPtr<IMFMediaType>& aMediaType);
    110 
    111  // Create a IMFMediaType which includes the details about the stream.
    112  // https://docs.microsoft.com/en-us/windows/win32/medfound/media-type-attributes
    113  virtual HRESULT CreateMediaType(const TrackInfo& aInfo,
    114                                  IMFMediaType** aMediaType) = 0;
    115 
    116  // True if the stream already has enough raw data.
    117  virtual bool HasEnoughRawData() const = 0;
    118 
    119  HRESULT CreateInputSample(IMFSample** aSample);
    120  void ReplySampleRequestIfPossible();
    121  bool ShouldServeSamples() const;
    122 
    123  void NotifyNewData(MediaRawData* aSample);
    124  void NotifyEndOfStreamInternal();
    125 
    126  virtual bool IsEnded() const;
    127 
    128  // Overwrite this method if inherited class needs to perform clean up on the
    129  // task queue when the stream gets shutdowned.
    130  virtual void ShutdownCleanUpOnTaskQueue() {};
    131 
    132  // Inherited class must implement this method to return decoded data. it
    133  // should uses `mRawDataQueueForGeneratingOutput` to generate output.
    134  virtual already_AddRefed<MediaData> OutputDataInternal() = 0;
    135 
    136  virtual void SendRequestSampleEvent(bool aIsEnough);
    137 
    138  HRESULT AddEncryptAttributes(IMFSample* aSample,
    139                               const CryptoSample& aCryptoConfig);
    140 
    141  void NotifyEndEvent();
    142 
    143  void AssertOnTaskQueue() const;
    144  void AssertOnMFThreadPool() const;
    145 
    146  // IMFMediaEventQueue is thread-safe.
    147  Microsoft::WRL::ComPtr<IMFMediaEventQueue> mMediaEventQueue;
    148  Microsoft::WRL::ComPtr<IMFStreamDescriptor> mStreamDescriptor;
    149  Microsoft::WRL::ComPtr<MFMediaSource> mParentSource;
    150 
    151  // This an unique ID retrieved from the IMFStreamDescriptor.
    152  DWORD mStreamDescriptorId = 0;
    153 
    154  // A unique ID assigned by MFMediaSource, which won't be changed after first
    155  // assignment.
    156  uint64_t mStreamId = 0;
    157 
    158  RefPtr<TaskQueue> mTaskQueue;
    159 
    160  // This class would be run on three threads, MF thread pool, the source's
    161  // task queue and MediaPDecoder (wrapper thread). Following members would be
    162  // used across both threads so they need to be thread-safe.
    163 
    164  // Modify on the MF thread pool, access from any threads.
    165  Atomic<bool> mIsShutdown;
    166 
    167  // True if the stream is selected by the media source.
    168  // Modify on MF thread pool, access from any threads.
    169  Atomic<bool> mIsSelected;
    170 
    171  // A thread-safe queue storing input samples, which provides samples to the
    172  // media engine.
    173  MediaQueue<MediaRawData> mRawDataQueueForFeedingEngine;
    174 
    175  // A thread-safe queue storing input samples, which would be used to generate
    176  // decoded data.
    177  MediaQueue<MediaRawData> mRawDataQueueForGeneratingOutput;
    178 
    179  // Thread-safe members END
    180 
    181  // Store sample request token, one token should be related with one output
    182  // data. It's used on the task queue only.
    183  std::queue<Microsoft::WRL::ComPtr<IUnknown>> mSampleRequestTokens;
    184 
    185  // Notify when playback reachs the end for this track.
    186  MediaEventProducer<TrackInfo::TrackType> mEndedEvent;
    187 
    188  // True if the stream has received the last data, but it could be reset if the
    189  // stream starts delivering more data. Used on the task queue only.
    190  bool mReceivedEOS;
    191 
    192  // https://github.com/w3c/encrypted-media/issues/251#issuecomment-819783073
    193  bool mIsEncryptedCustomInit;
    194 };
    195 
    196 /**
    197 * This wrapper helps to dispatch task onto the stream's task queue. Its methods
    198 * are not thread-safe and would only be called on the IPC decoder manager
    199 * thread.
    200 */
    201 class MFMediaEngineStreamWrapper final : public MediaDataDecoder {
    202 public:
    203  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MFMediaEngineStreamWrapper, final);
    204 
    205  MFMediaEngineStreamWrapper(MFMediaEngineStream* aStream,
    206                             TaskQueue* aTaskQueue,
    207                             const CreateDecoderParams& aParams)
    208      : mStream(aStream), mTaskQueue(aTaskQueue) {
    209    MOZ_ASSERT(mStream);
    210    MOZ_ASSERT(mTaskQueue);
    211  }
    212 
    213  // Methods for MediaDataDecoder, they are all called on the remote
    214  // decoder manager thread.
    215  RefPtr<InitPromise> Init() override;
    216  RefPtr<DecodePromise> Decode(MediaRawData* aSample) override;
    217  RefPtr<DecodePromise> Drain() override;
    218  RefPtr<FlushPromise> Flush() override;
    219  RefPtr<ShutdownPromise> Shutdown() override;
    220  nsCString GetDescriptionName() const override;
    221  nsCString GetCodecName() const override;
    222  ConversionRequired NeedsConversion() const override;
    223  bool ShouldDecoderAlwaysBeRecycled() const override;
    224 
    225  bool IsHardwareAccelerated(nsACString& aFailureReason) const override;
    226 
    227 private:
    228  ~MFMediaEngineStreamWrapper() = default;
    229 
    230  Microsoft::WRL::ComPtr<MFMediaEngineStream> mStream;
    231  RefPtr<TaskQueue> mTaskQueue;
    232 };
    233 
    234 }  // namespace mozilla
    235 
    236 #endif  // DOM_MEDIA_PLATFORM_WMF_MFMEDIAENGINESTREAM_H