AppleVTEncoder.h (4416B)
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_AppleVTEncoder_h_ 8 #define mozilla_AppleVTEncoder_h_ 9 10 #include <CoreMedia/CoreMedia.h> 11 #include <VideoToolbox/VideoToolbox.h> 12 13 #include "PlatformEncoderModule.h" 14 #include "apple/AppleUtils.h" 15 16 namespace mozilla { 17 18 namespace layers { 19 class Image; 20 } 21 22 class AppleVTEncoder final : public MediaDataEncoder { 23 public: 24 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AppleVTEncoder, final); 25 26 AppleVTEncoder(const EncoderConfig& aConfig, 27 const RefPtr<TaskQueue>& aTaskQueue) 28 : mConfig(aConfig), 29 mTaskQueue(aTaskQueue), 30 mHardwareNotAllowed(aConfig.mHardwarePreference == 31 HardwarePreference::RequireSoftware), 32 mError(NS_OK), 33 mSession(nullptr), 34 mTimer(nullptr) { 35 MOZ_ASSERT(mConfig.mSize.width > 0 && mConfig.mSize.height > 0); 36 MOZ_ASSERT(mTaskQueue); 37 } 38 39 RefPtr<InitPromise> Init() override; 40 RefPtr<EncodePromise> Encode(const MediaData* aSample) override; 41 RefPtr<EncodePromise> Encode(nsTArray<RefPtr<MediaData>>&& aSamples) override; 42 RefPtr<ReconfigurationPromise> Reconfigure( 43 const RefPtr<const EncoderConfigurationChangeList>& aConfigurationChanges) 44 override; 45 RefPtr<EncodePromise> Drain() override; 46 RefPtr<ShutdownPromise> Shutdown() override; 47 RefPtr<GenericPromise> SetBitrate(uint32_t aBitsPerSec) override; 48 bool IsHardwareAccelerated(nsACString& aFailureReason) const override { 49 return mIsHardwareAccelerated; 50 } 51 52 nsCString GetDescriptionName() const override { 53 return mIsHardwareAccelerated ? "apple hardware VT encoder"_ns 54 : "apple software VT encoder"_ns; 55 } 56 57 void OutputFrame(OSStatus aStatus, VTEncodeInfoFlags aFlags, 58 CMSampleBufferRef aBuffer); 59 60 private: 61 enum class EncodeResult { Success, EncodeError, FrameDropped, EmptyBuffer }; 62 63 virtual ~AppleVTEncoder() { MOZ_ASSERT(!mSession); } 64 void ProcessEncode(const RefPtr<const VideoData>& aSample); 65 RefPtr<ReconfigurationPromise> ProcessReconfigure( 66 const RefPtr<const EncoderConfigurationChangeList>& 67 aConfigurationChanges); 68 void ProcessOutput(RefPtr<MediaRawData>&& aOutput, EncodeResult aResult); 69 void ForceOutputIfNeeded(); 70 void MaybeResolveOrRejectEncodePromise(); 71 RefPtr<EncodePromise> ProcessDrain(); 72 RefPtr<ShutdownPromise> ProcessShutdown(); 73 74 void InvalidateSessionIfNeeded(); 75 MediaResult InitSession(); 76 CFDictionaryRef BuildSourceImageBufferAttributes(OSType aPixelFormat); 77 CVPixelBufferRef CreateCVPixelBuffer(layers::Image* aSource); 78 bool WriteExtraData(MediaRawData* aDst, CMSampleBufferRef aSrc, 79 const bool aAsAnnexB); 80 81 bool SetAverageBitrate(uint32_t aBitsPerSec); 82 bool SetConstantBitrate(uint32_t aBitsPerSec); 83 bool SetBitrateAndMode(BitrateMode aBitrateMode, uint32_t aBitsPerSec); 84 bool SetFrameRate(int64_t aFPS); 85 bool SetRealtime(bool aEnabled); 86 bool SetProfileLevel(H264_PROFILE aValue); 87 bool IsSettingColorSpaceSupported() const; 88 MediaResult SetColorSpace(const EncoderConfig::SampleFormat& aFormat); 89 90 void EncodeNextSample(nsTArray<RefPtr<MediaData>>&& aInputs, 91 MediaDataEncoder::EncodedData&& aOutputs); 92 93 void AssertOnTaskQueue() { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); } 94 95 EncoderConfig mConfig; 96 const RefPtr<TaskQueue> mTaskQueue; 97 const bool mHardwareNotAllowed; 98 // Accessed only in mTaskQueue. 99 EncodedData mEncodedData; 100 // Accessed only in mTaskQueue. 101 MozPromiseHolder<EncodePromise> mEncodePromise; 102 MozPromiseHolder<EncodePromise> mEncodeBatchPromise; 103 MozPromiseRequestHolder<EncodePromise> mEncodeBatchRequest; 104 RefPtr<MediaByteBuffer> mAvcc; // Stores latest avcC data. 105 MediaResult mError; 106 107 // Written by Init() but used only in task queue. 108 AutoCFTypeRef<VTCompressionSessionRef> mSession; 109 // Can be accessed on any thread, but only written on during init. 110 Atomic<bool> mIsHardwareAccelerated; 111 // Accessed only in mTaskQueue. Used for for OS versions < 11. 112 nsCOMPtr<nsITimer> mTimer; 113 }; 114 115 } // namespace mozilla 116 117 #endif // mozilla_AppleVTEncoder_h_