EncoderConfig.h (9408B)
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_EncoderConfig_h_ 8 #define mozilla_EncoderConfig_h_ 9 10 #include "H264.h" 11 #include "MediaResult.h" 12 #include "mozilla/Result.h" 13 #include "mozilla/Variant.h" 14 #include "mozilla/dom/ImageBitmapBinding.h" 15 #include "mozilla/ipc/IPCCore.h" 16 17 namespace mozilla { 18 19 namespace layers { 20 class Image; 21 } // namespace layers 22 23 MOZ_DEFINE_ENUM_CLASS_WITH_TOSTRING(CodecType, 24 (_BeginVideo_, H264, H265, VP8, VP9, AV1, 25 _EndVideo_, _BeginAudio_, Opus, Vorbis, 26 Flac, AAC, PCM, G722, _EndAudio_, 27 Unknown)); 28 29 constexpr bool IsVideo(CodecType aCodecType) { 30 return aCodecType > CodecType::_BeginVideo_ && 31 aCodecType < CodecType::_EndVideo_; 32 } 33 constexpr bool IsAudio(CodecType aCodecType) { 34 return aCodecType > CodecType::_BeginAudio_ && 35 aCodecType < CodecType::_EndAudio_; 36 } 37 38 enum class Usage { 39 Realtime, // Low latency prefered 40 Record 41 }; 42 enum class BitrateMode { Constant, Variable }; 43 // Scalable Video Coding (SVC) settings for WebCodecs: 44 // https://www.w3.org/TR/webrtc-svc/ 45 enum class ScalabilityMode { None, L1T2, L1T3 }; 46 47 enum class HardwarePreference { None, RequireHardware, RequireSoftware }; 48 49 const char* YUVColorSpaceToString(const gfx::YUVColorSpace& aYUVColorSpace); 50 const char* ColorSpace2ToString(const gfx::ColorSpace2& aColorSpace2); 51 const char* TransferFunctionToString( 52 const gfx::TransferFunction& aTransferFunction); 53 54 enum class H264BitStreamFormat { AVC, ANNEXB }; 55 56 struct H264Specific final { 57 H264_PROFILE mProfile{H264_PROFILE::H264_PROFILE_UNKNOWN}; 58 H264_LEVEL mLevel{H264_LEVEL::H264_LEVEL_1}; 59 H264BitStreamFormat mFormat{H264BitStreamFormat::AVC}; 60 61 H264Specific() = default; 62 H264Specific(H264_PROFILE aProfile, H264_LEVEL aLevel, 63 H264BitStreamFormat aFormat) 64 : mProfile(aProfile), mLevel(aLevel), mFormat(aFormat) {} 65 }; 66 67 enum class OpusBitstreamFormat { Opus, OGG }; 68 69 // The default values come from the Web Codecs specification. 70 struct OpusSpecific final { 71 enum class Application { Unspecified, Voip, Audio, RestricedLowDelay }; 72 Application mApplication = Application::Unspecified; 73 uint64_t mFrameDuration = 20000; // microseconds 74 uint8_t mComplexity = 10; // 0-10 75 OpusBitstreamFormat mFormat = OpusBitstreamFormat::Opus; 76 uint64_t mPacketLossPerc = 0; // 0-100 77 bool mUseInBandFEC = false; 78 bool mUseDTX = false; 79 }; 80 81 enum class VPXComplexity { Normal, High, Higher, Max }; 82 struct VP8Specific { 83 VP8Specific() = default; 84 // Ignore webrtc::VideoCodecVP8::errorConcealmentOn, 85 // for it's always false in the codebase (except libwebrtc test cases). 86 VP8Specific(const VPXComplexity aComplexity, const bool aResilience, 87 const uint8_t aNumTemporalLayers, const bool aDenoising, 88 const bool aAutoResize, const bool aFrameDropping) 89 : mComplexity(aComplexity), 90 mResilience(aResilience), 91 mNumTemporalLayers(aNumTemporalLayers), 92 mDenoising(aDenoising), 93 mAutoResize(aAutoResize), 94 mFrameDropping(aFrameDropping) {} 95 VPXComplexity mComplexity{VPXComplexity::Normal}; 96 bool mResilience{true}; 97 uint8_t mNumTemporalLayers{1}; 98 bool mDenoising{true}; 99 bool mAutoResize{false}; 100 bool mFrameDropping{false}; 101 }; 102 103 struct VP9Specific : public VP8Specific { 104 VP9Specific() = default; 105 VP9Specific(const VPXComplexity aComplexity, const bool aResilience, 106 const uint8_t aNumTemporalLayers, const bool aDenoising, 107 const bool aAutoResize, const bool aFrameDropping, 108 const bool aAdaptiveQp, const uint8_t aNumSpatialLayers, 109 const bool aFlexible) 110 : VP8Specific(aComplexity, aResilience, aNumTemporalLayers, aDenoising, 111 aAutoResize, aFrameDropping), 112 mAdaptiveQp(aAdaptiveQp), 113 mNumSpatialLayers(aNumSpatialLayers), 114 mFlexible(aFlexible) {} 115 bool mAdaptiveQp{true}; 116 uint8_t mNumSpatialLayers{1}; 117 bool mFlexible{false}; 118 }; 119 120 // A class that holds the intial configuration of an encoder. For simplicity, 121 // this is used for both audio and video encoding. Members irrelevant to the 122 // instance are to be ignored, and are set at their default value. 123 class EncoderConfig final { 124 public: 125 using CodecSpecific = 126 Variant<void_t, H264Specific, OpusSpecific, VP8Specific, VP9Specific>; 127 128 struct VideoColorSpace { 129 Maybe<gfx::ColorRange> mRange; 130 Maybe<gfx::YUVColorSpace> mMatrix; 131 Maybe<gfx::ColorSpace2> mPrimaries; 132 Maybe<gfx::TransferFunction> mTransferFunction; 133 134 VideoColorSpace() = default; 135 VideoColorSpace(const gfx::ColorRange& aColorRange, 136 const gfx::YUVColorSpace& aMatrix, 137 const gfx::ColorSpace2& aPrimaries, 138 const gfx::TransferFunction& aTransferFunction) 139 : mRange(Some(aColorRange)), 140 mMatrix(Some(aMatrix)), 141 mPrimaries(Some(aPrimaries)), 142 mTransferFunction(Some(aTransferFunction)) {} 143 144 bool operator==(const VideoColorSpace& aOther) const { 145 return mRange == aOther.mRange && mMatrix == aOther.mMatrix && 146 mPrimaries == aOther.mPrimaries && 147 mTransferFunction == aOther.mTransferFunction; 148 } 149 bool operator!=(const VideoColorSpace& aOther) const { 150 return !(*this == aOther); 151 } 152 nsCString ToString() const; 153 }; 154 155 struct SampleFormat { 156 dom::ImageBitmapFormat mPixelFormat; 157 VideoColorSpace mColorSpace; 158 159 SampleFormat(const dom::ImageBitmapFormat& aPixelFormat, 160 const VideoColorSpace& aColorSpace) 161 : mPixelFormat(aPixelFormat), mColorSpace(aColorSpace) {} 162 explicit SampleFormat(const dom::ImageBitmapFormat& aPixelFormat) 163 : mPixelFormat(aPixelFormat) {} 164 165 bool operator==(const SampleFormat& aOther) const { 166 return mPixelFormat == aOther.mPixelFormat && 167 mColorSpace == aOther.mColorSpace; 168 } 169 bool operator!=(const SampleFormat& aOther) const { 170 return !(*this == aOther); 171 } 172 173 nsCString ToString() const; 174 175 bool IsRGB32() const { 176 return mPixelFormat == dom::ImageBitmapFormat::BGRA32 || 177 mPixelFormat == dom::ImageBitmapFormat::RGBA32; 178 } 179 bool IsYUV() const { 180 return mPixelFormat == dom::ImageBitmapFormat::YUV444P || 181 mPixelFormat == dom::ImageBitmapFormat::YUV422P || 182 mPixelFormat == dom::ImageBitmapFormat::YUV420P || 183 mPixelFormat == dom::ImageBitmapFormat::YUV420SP_NV12 || 184 mPixelFormat == dom::ImageBitmapFormat::YUV420SP_NV21; 185 } 186 187 static Result<SampleFormat, MediaResult> FromImage(layers::Image* aImage); 188 }; 189 190 EncoderConfig() = default; 191 EncoderConfig(const EncoderConfig& aConfig) = default; 192 193 // This constructor is used for video encoders 194 EncoderConfig(const CodecType aCodecType, gfx::IntSize aSize, 195 const Usage aUsage, const SampleFormat& aFormat, 196 const uint32_t aFramerate, const size_t aKeyframeInterval, 197 const uint32_t aBitrate, const uint32_t aMinBitrate, 198 const uint32_t aMaxBitrate, const BitrateMode aBitrateMode, 199 const HardwarePreference aHardwarePreference, 200 const ScalabilityMode aScalabilityMode, 201 const CodecSpecific& aCodecSpecific) 202 : mCodec(aCodecType), 203 mSize(aSize), 204 mBitrateMode(aBitrateMode), 205 mBitrate(aBitrate), 206 mMinBitrate(aMinBitrate), 207 mMaxBitrate(aMaxBitrate), 208 mUsage(aUsage), 209 mHardwarePreference(aHardwarePreference), 210 mFormat(aFormat), 211 mScalabilityMode(aScalabilityMode), 212 mFramerate(aFramerate), 213 mKeyframeInterval(aKeyframeInterval), 214 mCodecSpecific(aCodecSpecific) { 215 MOZ_ASSERT(IsVideo()); 216 } 217 218 // This constructor is used for audio encoders 219 EncoderConfig(const CodecType aCodecType, uint32_t aNumberOfChannels, 220 const BitrateMode aBitrateMode, uint32_t aSampleRate, 221 uint32_t aBitrate, const CodecSpecific& aCodecSpecific) 222 : mCodec(aCodecType), 223 mBitrateMode(aBitrateMode), 224 mBitrate(aBitrate), 225 mNumberOfChannels(aNumberOfChannels), 226 mSampleRate(aSampleRate), 227 mCodecSpecific(aCodecSpecific) { 228 MOZ_ASSERT(IsAudio()); 229 } 230 231 nsCString ToString() const; 232 233 bool IsVideo() const { return mozilla::IsVideo(mCodec); } 234 235 bool IsAudio() const { return mozilla::IsAudio(mCodec); } 236 237 CodecType mCodec{}; 238 gfx::IntSize mSize{}; 239 BitrateMode mBitrateMode{}; 240 uint32_t mBitrate{}; 241 uint32_t mMinBitrate{}; 242 uint32_t mMaxBitrate{}; 243 Usage mUsage{Usage::Record}; 244 // Video-only 245 HardwarePreference mHardwarePreference{HardwarePreference::None}; 246 SampleFormat mFormat{dom::ImageBitmapFormat::YUV420P}; 247 ScalabilityMode mScalabilityMode{}; 248 uint32_t mFramerate{}; 249 size_t mKeyframeInterval{}; 250 // Audio-only 251 uint32_t mNumberOfChannels{}; 252 uint32_t mSampleRate{}; 253 CodecSpecific mCodecSpecific{void_t{}}; 254 }; 255 256 } // namespace mozilla 257 258 #endif // mozilla_EncoderConfig_h_