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