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 "PlatformDecoderModule.h" 10 # include "mozilla/Span.h" 11 12 # include <stdint.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 NS_LITERAL_CSTRING("libvpx video decoder"); 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::UNKNOWN; 94 } 95 } 96 97 /* 98 mFullRange == false then: 99 For BitDepth equals 8: 100 Y is between 16 and 235 inclusive. 101 U and V are between 16 and 240 inclusive. 102 For BitDepth equals 10: 103 Y is between 64 and 940 inclusive. 104 U and V are between 64 and 960 inclusive. 105 For BitDepth equals 12: 106 Y is between 256 and 3760. 107 U and V are between 256 and 3840 inclusive. 108 mFullRange == true then: 109 No restriction on Y, U, V values. 110 */ 111 bool mFullRange = false; 112 ColorRangeVPXStreamInfo113 gfx::ColorRange ColorRange() const { 114 return mFullRange ? gfx::ColorRange::FULL : gfx::ColorRange::LIMITED; 115 } 116 117 /* 118 Sub-sampling, used only for non sRGB colorspace. 119 subsampling_x subsampling_y Description 120 0 0 YUV 4:4:4 121 0 1 YUV 4:4:0 122 1 0 YUV 4:2:2 123 1 1 YUV 4:2:0 124 */ 125 bool mSubSampling_x = true; 126 bool mSubSampling_y = true; 127 IsCompatibleVPXStreamInfo128 bool IsCompatible(const VPXStreamInfo& aOther) const { 129 return mImage == aOther.mImage && mProfile == aOther.mProfile && 130 mBitDepth == aOther.mBitDepth && 131 mSubSampling_x == aOther.mSubSampling_x && 132 mSubSampling_y == aOther.mSubSampling_y && 133 mColorSpace == aOther.mColorSpace && 134 mFullRange == aOther.mFullRange; 135 } 136 }; 137 138 static bool GetStreamInfo(Span<const uint8_t> aBuffer, VPXStreamInfo& aInfo, 139 Codec aCodec); 140 141 private: 142 ~VPXDecoder(); 143 RefPtr<DecodePromise> ProcessDecode(MediaRawData* aSample); 144 MediaResult DecodeAlpha(vpx_image_t** aImgAlpha, const MediaRawData* aSample); 145 146 const RefPtr<layers::ImageContainer> mImageContainer; 147 RefPtr<layers::KnowsCompositor> mImageAllocator; 148 const RefPtr<TaskQueue> mTaskQueue; 149 150 // VPx decoder state 151 vpx_codec_ctx_t mVPX; 152 153 // VPx alpha decoder state 154 vpx_codec_ctx_t mVPXAlpha; 155 156 const VideoInfo& mInfo; 157 158 const Codec mCodec; 159 const bool mLowLatency; 160 }; 161 162 } // namespace mozilla 163 164 #endif 165