WMFMediaDataEncoder.h (3798B)
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 WMFMediaDataEncoder_h_ 8 #define WMFMediaDataEncoder_h_ 9 10 #include <comdef.h> 11 12 #include "MFTEncoder.h" 13 #include "PlatformEncoderModule.h" 14 #include "WMFDataEncoderUtils.h" 15 #include "WMFUtils.h" 16 #include "mozilla/WindowsProcessMitigations.h" 17 18 namespace mozilla { 19 20 class WMFMediaDataEncoder final : public MediaDataEncoder { 21 public: 22 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WMFMediaDataEncoder, final); 23 24 WMFMediaDataEncoder(const EncoderConfig& aConfig, 25 const RefPtr<TaskQueue>& aTaskQueue); 26 27 RefPtr<InitPromise> Init() override; 28 RefPtr<EncodePromise> Encode(const MediaData* aSample) override; 29 RefPtr<EncodePromise> Encode(nsTArray<RefPtr<MediaData>>&& aSamples) override; 30 RefPtr<EncodePromise> Drain() override; 31 RefPtr<ShutdownPromise> Shutdown() override; 32 RefPtr<GenericPromise> SetBitrate(uint32_t aBitsPerSec) override; 33 bool IsHardwareAccelerated(nsACString& aFailureReason) const override { 34 return mIsHardwareAccelerated; 35 } 36 37 RefPtr<ReconfigurationPromise> Reconfigure( 38 const RefPtr<const EncoderConfigurationChangeList>& aConfigurationChanges) 39 override; 40 nsCString GetDescriptionName() const override; 41 42 private: 43 ~WMFMediaDataEncoder() = default; 44 45 // Automatically lock/unlock IMFMediaBuffer. 46 class LockBuffer final { 47 public: 48 explicit LockBuffer(RefPtr<IMFMediaBuffer>& aBuffer) : mBuffer(aBuffer) { 49 mResult = mBuffer->Lock(&mBytes, &mCapacity, &mLength); 50 } 51 52 ~LockBuffer() { 53 if (SUCCEEDED(mResult)) { 54 mBuffer->Unlock(); 55 } 56 } 57 58 BYTE* Data() { return mBytes; } 59 DWORD Capacity() { return mCapacity; } 60 DWORD Length() { return mLength; } 61 HRESULT Result() { return mResult; } 62 63 private: 64 RefPtr<IMFMediaBuffer> mBuffer; 65 BYTE* mBytes{}; 66 DWORD mCapacity{}; 67 DWORD mLength{}; 68 HRESULT mResult{}; 69 }; 70 71 RefPtr<InitPromise> ProcessInit(); 72 73 HRESULT InitMFTEncoder(RefPtr<MFTEncoder>& aEncoder); 74 void InitializeConfigData(); 75 void SetConfigData(const nsTArray<UINT8>& aHeader); 76 77 RefPtr<EncodePromise> ProcessEncode(RefPtr<const VideoData>&& aSample); 78 RefPtr<EncodePromise> ProcessEncodeBatch( 79 nsTArray<RefPtr<const VideoData>>&& aSamples); 80 RefPtr<EncodePromise> ProcessDrain(); 81 82 already_AddRefed<IMFSample> ConvertToNV12InputSample( 83 RefPtr<const VideoData>&& aData); 84 85 EncodedData ProcessOutputSamples( 86 nsTArray<MFTEncoder::OutputSample>&& aSamples); 87 already_AddRefed<MediaRawData> OutputSampleToMediaData( 88 MFTEncoder::OutputSample& aSample); 89 90 bool WriteFrameData(RefPtr<MediaRawData>& aDest, LockBuffer& aSrc, 91 bool aIsKeyframe); 92 93 bool IsAnnexB() const; 94 95 void AssertOnTaskQueue() { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); } 96 97 EncoderConfig mConfig; 98 const RefPtr<TaskQueue> mTaskQueue; 99 const bool mHardwareNotAllowed; 100 RefPtr<MFTEncoder> mEncoder; 101 // SPS/PPS NALUs when encoding in AnnexB usage, avcC otherwise. 102 RefPtr<MediaByteBuffer> mConfigData; 103 104 // Can be accessed on any thread, but only written on during init. 105 Atomic<bool> mIsHardwareAccelerated; 106 107 // Both Encode and EncodeBatch share mEncodePromise and mEncodeRequest, as 108 // concurrent calls are not allowed. 109 MozPromiseHolder<EncodePromise> mEncodePromise; 110 MozPromiseRequestHolder<MFTEncoder::EncodePromise> mEncodeRequest; 111 112 MozPromiseHolder<EncodePromise> mDrainPromise; 113 MozPromiseRequestHolder<MFTEncoder::EncodePromise> mDrainRequest; 114 }; 115 116 } // namespace mozilla 117 118 #endif