MFMediaEngineVideoStream.h (4651B)
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_MFMEDIAENGINEVIDEOSTREAM_H 6 #define DOM_MEDIA_PLATFORM_WMF_MFMEDIAENGINEVIDEOSTREAM_H 7 8 #include "MFMediaEngineStream.h" 9 #include "WMFUtils.h" 10 #include "mozilla/Mutex.h" 11 12 namespace mozilla { 13 namespace layers { 14 15 class Image; 16 class DcompSurfaceImage; 17 18 } // namespace layers 19 20 class MFMediaSource; 21 class MediaRawData; 22 23 class MFMediaEngineVideoStream final : public MFMediaEngineStream { 24 public: 25 MFMediaEngineVideoStream() = default; 26 27 static MFMediaEngineVideoStream* Create(uint64_t aStreamId, 28 const TrackInfo& aInfo, 29 bool aIsEncryptedCustomInit, 30 MFMediaSource* aParentSource); 31 nsCString GetDescriptionName() const override { 32 return "media engine video stream"_ns; 33 } 34 35 nsCString GetCodecName() const override; 36 37 TrackInfo::TrackType TrackType() override { 38 return TrackInfo::TrackType::kVideoTrack; 39 } 40 41 void SetKnowsCompositor(layers::KnowsCompositor* aKnowsCompositor); 42 43 void SetDCompSurfaceHandle(HANDLE aDCompSurfaceHandle, gfx::IntSize aDisplay); 44 45 MFMediaEngineVideoStream* AsVideoStream() override { return this; } 46 47 MediaDataDecoder::ConversionRequired NeedsConversion() const override; 48 49 // Called by MFMediaEngineParent when we are creating a video decoder for 50 // the remote decoder. This is used to detect if the inband video config 51 // change happens during playback. 52 void SetConfig(const TrackInfo& aConfig); 53 54 RefPtr<MediaDataDecoder::DecodePromise> OutputData( 55 RefPtr<MediaRawData> aSample) override; 56 57 RefPtr<MediaDataDecoder::DecodePromise> Drain() override; 58 59 RefPtr<MediaDataDecoder::FlushPromise> Flush() override; 60 61 bool IsEncrypted() const override; 62 63 private: 64 HRESULT 65 CreateMediaType(const TrackInfo& aInfo, IMFMediaType** aMediaType) override; 66 67 bool HasEnoughRawData() const override; 68 69 void UpdateConfig(const VideoInfo& aInfo); 70 71 already_AddRefed<MediaData> OutputDataInternal() override; 72 73 bool IsDCompImageReady(); 74 75 // Those promises are used to handle decode/drain which happens before the 76 // Dcomp surface is ready. 77 void ResolvePendingPromisesIfNeeded(); 78 79 void ShutdownCleanUpOnTaskQueue() override; 80 81 bool IsEnded() const override; 82 83 // Before Dcomp surface is ready, we can't return any video data due to 84 // lacking of the image, which should only happen on the beginning of the 85 // video playback. In that situation, once we have enough video raw data, we 86 // can stop delaying the decode promise by waiting the Dcomp surface and 87 // resolveing the promise when Dcomp surface is ready. Doing so helps to keep 88 // the decode promise pending, so that the MFR won't keep sending more input 89 // data, which we actually don't need that many. 90 bool ShouldDelayVideoDecodeBeforeDcompReady(); 91 92 void SendRequestSampleEvent(bool aIsEnough) override; 93 94 // Task queue only members. 95 HANDLE mDCompSurfaceHandle; 96 bool mNeedRecreateImage; 97 RefPtr<layers::KnowsCompositor> mKnowsCompositor; 98 99 Mutex mMutex{"MFMediaEngineVideoStream"}; 100 gfx::IntSize mDisplay MOZ_GUARDED_BY(mMutex); 101 102 // Set on the initialization, won't be changed after that. 103 WMFStreamType mStreamType; 104 105 // Created and accessed in the decoder thread. 106 RefPtr<layers::DcompSurfaceImage> mDcompSurfaceImage; 107 108 // This flag is used to check if the video config changes detected by the 109 // media config monitor. When the video decoder get created first, we will set 110 // this flag to true, then we know any config being set afterward indicating 111 // a new config change. 112 bool mHasReceivedInitialCreateDecoderConfig; 113 114 // When draining, the track should return all decoded data. However, if the 115 // dcomp image hasn't been ready yet, then we won't have any decoded data to 116 // return. This promise is used for that case, and will be resolved once we 117 // have dcomp image. 118 MozPromiseHolder<MediaDataDecoder::DecodePromise> mPendingDrainPromise; 119 120 // The promise used to return all video output which are requested before the 121 // Dcomp surface is ready. This should only be used once in entire playback, 122 // typically happening around the beginning of the playback. 123 MozPromiseHolder<MediaDataDecoder::DecodePromise> 124 mVideoDecodeBeforeDcompPromise; 125 126 // Set when `CreateMediaType()` is called. 127 bool mIsEncrypted = false; 128 }; 129 130 } // namespace mozilla 131 132 #endif // DOM_MEDIA_PLATFORM_WMF_MFMEDIAENGINEVIDEOSTREAM_H