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 #if !defined(VPXDecoder_h_) 7 # define VPXDecoder_h_ 8 9 # include <stdint.h> 10 11 # include "PlatformDecoderModule.h" 12 # include "mozilla/Span.h" 13 # include "mozilla/gfx/Types.h" 14 # include "vpx/vp8dx.h" 15 # include "vpx/vpx_codec.h" 16 # include "vpx/vpx_decoder.h" 17 18 namespace mozilla { 19 20 DDLoggedTypeDeclNameAndBase(VPXDecoder, MediaDataDecoder); 21 22 class VPXDecoder : public MediaDataDecoder, 23 public DecoderDoctorLifeLogger<VPXDecoder> { 24 public: 25 explicit VPXDecoder(const CreateDecoderParams& aParams); 26 27 RefPtr<InitPromise> Init() override; 28 RefPtr<DecodePromise> Decode(MediaRawData* aSample) override; 29 RefPtr<DecodePromise> Drain() override; 30 RefPtr<FlushPromise> Flush() override; 31 RefPtr<ShutdownPromise> Shutdown() override; GetDescriptionName()32 nsCString GetDescriptionName() const override { 33 return "libvpx video decoder"_ns; 34 } 35 36 enum Codec : uint8_t { 37 VP8 = 1 << 0, 38 VP9 = 1 << 1, 39 Unknown = 1 << 7, 40 }; 41 42 // Return true if aMimeType is a one of the strings used by our demuxers to 43 // identify VPX of the specified type. Does not parse general content type 44 // strings, i.e. white space matters. 45 static bool IsVPX(const nsACString& aMimeType, 46 uint8_t aCodecMask = VP8 | VP9); 47 static bool IsVP8(const nsACString& aMimeType); 48 static bool IsVP9(const nsACString& aMimeType); 49 50 // Return true if a sample is a keyframe for the specified codec. 51 static bool IsKeyframe(Span<const uint8_t> aBuffer, Codec aCodec); 52 53 // Return the frame dimensions for a sample for the specified codec. 54 static gfx::IntSize GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec); 55 // Return the display dimensions for a sample for the specified codec. 56 static gfx::IntSize GetDisplaySize(Span<const uint8_t> aBuffer, Codec aCodec); 57 58 // Return the VP9 profile as per https://www.webmproject.org/vp9/profiles/ 59 // Return negative value if error. 60 static int GetVP9Profile(Span<const uint8_t> aBuffer); 61 62 struct VPXStreamInfo { 63 gfx::IntSize mImage; 64 gfx::IntSize mDisplay; 65 bool mKeyFrame = false; 66 67 uint8_t mProfile = 0; 68 uint8_t mBitDepth = 8; 69 /* 70 0 CS_UNKNOWN Unknown (in this case the color space must be signaled outside 71 the VP9 bitstream). 72 1 CS_BT_601 Rec. ITU-R BT.601-7 73 2 CS_BT_709 Rec. ITU-R BT.709-6 74 3 CS_SMPTE_170 SMPTE-170 75 4 CS_SMPTE_240 SMPTE-240 76 5 CS_BT_2020 Rec. ITU-R BT.2020-2 77 6 CS_RESERVED Reserved 78 7 CS_RGB sRGB (IEC 61966-2-1) 79 */ 80 int mColorSpace = 1; // CS_BT_601 81 ColorSpaceVPXStreamInfo82 gfx::YUVColorSpace ColorSpace() const { 83 switch (mColorSpace) { 84 case 1: 85 case 3: 86 case 4: 87 return gfx::YUVColorSpace::BT601; 88 case 2: 89 return gfx::YUVColorSpace::BT709; 90 case 5: 91 return gfx::YUVColorSpace::BT2020; 92 default: 93 return gfx::YUVColorSpace::Default; 94 } 95 } 96 97 // Ref: ISO/IEC 23091-2:2019 98 enum class ColorPrimaries { 99 BT_709_6 = 1, 100 Unspecified = 2, 101 BT_470_6_M = 4, 102 BT_470_7_BG = 5, 103 BT_601_7 = 6, 104 SMPTE_ST_240 = 7, 105 Film = 8, 106 BT_2020_Nonconstant_Luminance = 9, 107 SMPTE_ST_428_1 = 10, 108 SMPTE_RP_431_2 = 11, 109 SMPTE_EG_432_1 = 12, 110 EBU_Tech_3213_E = 22, 111 }; 112 113 // Ref: ISO/IEC 23091-2:2019 114 enum class TransferCharacteristics { 115 BT_709_6 = 1, 116 Unspecified = 2, 117 BT_470_6_M = 4, 118 BT_470_7_BG = 5, 119 BT_601_7 = 6, 120 SMPTE_ST_240 = 7, 121 Linear = 8, 122 Logrithmic = 9, 123 Logrithmic_Sqrt = 10, 124 IEC_61966_2_4 = 11, 125 BT_1361_0 = 12, 126 IEC_61966_2_1 = 13, 127 BT_2020_10bit = 14, 128 BT_2020_12bit = 15, 129 SMPTE_ST_2084 = 16, 130 SMPTE_ST_428_1 = 17, 131 BT_2100_HLG = 18, 132 }; 133 134 enum class MatrixCoefficients { 135 Identity = 0, 136 BT_709_6 = 1, 137 Unspecified = 2, 138 FCC = 4, 139 BT_470_7_BG = 5, 140 BT_601_7 = 6, 141 SMPTE_ST_240 = 7, 142 YCgCo = 8, 143 BT_2020_Nonconstant_Luminance = 9, 144 BT_2020_Constant_Luminance = 10, 145 SMPTE_ST_2085 = 11, 146 Chromacity_Constant_Luminance = 12, 147 Chromacity_Nonconstant_Luminance = 13, 148 BT_2100_ICC = 14, 149 }; 150 151 /* 152 mFullRange == false then: 153 For BitDepth equals 8: 154 Y is between 16 and 235 inclusive. 155 U and V are between 16 and 240 inclusive. 156 For BitDepth equals 10: 157 Y is between 64 and 940 inclusive. 158 U and V are between 64 and 960 inclusive. 159 For BitDepth equals 12: 160 Y is between 256 and 3760. 161 U and V are between 256 and 3840 inclusive. 162 mFullRange == true then: 163 No restriction on Y, U, V values. 164 */ 165 bool mFullRange = false; 166 ColorRangeVPXStreamInfo167 gfx::ColorRange ColorRange() const { 168 return mFullRange ? gfx::ColorRange::FULL : gfx::ColorRange::LIMITED; 169 } 170 171 /* 172 Sub-sampling, used only for non sRGB colorspace. 173 subsampling_x subsampling_y Description 174 0 0 YUV 4:4:4 175 0 1 YUV 4:4:0 176 1 0 YUV 4:2:2 177 1 1 YUV 4:2:0 178 */ 179 bool mSubSampling_x = true; 180 bool mSubSampling_y = true; 181 IsCompatibleVPXStreamInfo182 bool IsCompatible(const VPXStreamInfo& aOther) const { 183 return mImage == aOther.mImage && mProfile == aOther.mProfile && 184 mBitDepth == aOther.mBitDepth && 185 mSubSampling_x == aOther.mSubSampling_x && 186 mSubSampling_y == aOther.mSubSampling_y && 187 mColorSpace == aOther.mColorSpace && 188 mFullRange == aOther.mFullRange; 189 } 190 }; 191 192 static bool GetStreamInfo(Span<const uint8_t> aBuffer, VPXStreamInfo& aInfo, 193 Codec aCodec); 194 195 static void GetVPCCBox(MediaByteBuffer* aDestBox, const VPXStreamInfo& aInfo); 196 197 private: 198 ~VPXDecoder(); 199 RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample); 200 MediaResult DecodeAlpha(vpx_image_t** aImgAlpha, const MediaRawData* aSample); 201 202 const RefPtr<layers::ImageContainer> mImageContainer; 203 RefPtr<layers::KnowsCompositor> mImageAllocator; 204 const RefPtr<TaskQueue> mTaskQueue; 205 206 // VPx decoder state 207 vpx_codec_ctx_t mVPX; 208 209 // VPx alpha decoder state 210 vpx_codec_ctx_t mVPXAlpha; 211 212 const VideoInfo mInfo; 213 214 const Codec mCodec; 215 const bool mLowLatency; 216 }; 217 218 } // namespace mozilla 219 220 #endif 221