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/. */
7 #include "WebCodecsUtils.h"
9 #include "VideoUtils.h"
10 #include "js/experimental/TypedData.h"
11 #include "mozilla/Assertions.h"
12 #include "mozilla/CheckedInt.h"
13 #include "mozilla/dom/ImageBitmapBinding.h"
14 #include "mozilla/dom/VideoColorSpaceBinding.h"
15 #include "mozilla/dom/VideoFrameBinding.h"
16 #include "mozilla/gfx/Types.h"
19 namespace mozilla::dom
{
22 * The followings are helpers for VideoDecoder methods
25 nsTArray
<nsCString
> GuessContainers(const nsAString
& aCodec
) {
26 if (IsAV1CodecString(aCodec
)) {
27 return {"mp4"_ns
, "webm"_ns
};
30 if (IsVP9CodecString(aCodec
)) {
31 return {"mp4"_ns
, "webm"_ns
, "ogg"_ns
};
34 if (IsVP8CodecString(aCodec
)) {
35 return {"webm"_ns
, "ogg"_ns
, "3gpp"_ns
, "3gpp2"_ns
, "3gp2"_ns
};
38 if (IsH264CodecString(aCodec
)) {
39 return {"mp4"_ns
, "3gpp"_ns
, "3gpp2"_ns
, "3gp2"_ns
};
46 * The below are helpers to operate ArrayBuffer or ArrayBufferView.
49 static std::tuple
<JS::ArrayBufferOrView
, size_t, size_t> GetArrayBufferInfo(
51 const OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer
& aBuffer
) {
52 if (aBuffer
.IsArrayBuffer()) {
53 const ArrayBuffer
& buffer
= aBuffer
.GetAsArrayBuffer();
58 JS::GetArrayBufferMaybeSharedLengthAndData(buffer
.Obj(), &length
,
61 return std::make_tuple(JS::ArrayBufferOrView::fromObject(buffer
.Obj()),
65 MOZ_ASSERT(aBuffer
.IsArrayBufferView());
66 const ArrayBufferView
& view
= aBuffer
.GetAsArrayBufferView();
68 JS::Rooted
<JSObject
*> obj(aCx
, view
.Obj());
69 return std::make_tuple(
70 JS::ArrayBufferOrView::fromObject(
71 JS_GetArrayBufferViewBuffer(aCx
, obj
, &isSharedMemory
)),
72 JS_GetArrayBufferViewByteOffset(obj
),
73 JS_GetArrayBufferViewByteLength(obj
));
76 Result
<Ok
, nsresult
> CloneBuffer(
78 OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer
& aDest
,
79 const OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer
& aSrc
) {
80 std::tuple
<JS::ArrayBufferOrView
, size_t, size_t> info
=
81 GetArrayBufferInfo(aCx
, aSrc
);
82 JS::Rooted
<JS::ArrayBufferOrView
> abov(aCx
);
83 abov
.set(std::get
<0>(info
));
84 size_t offset
= std::get
<1>(info
);
85 size_t len
= std::get
<2>(info
);
86 if (NS_WARN_IF(!abov
)) {
87 return Err(NS_ERROR_UNEXPECTED
);
90 JS::Rooted
<JSObject
*> obj(aCx
, abov
.asObject());
91 JS::Rooted
<JSObject
*> cloned(aCx
,
92 JS::ArrayBufferClone(aCx
, obj
, offset
, len
));
93 if (NS_WARN_IF(!cloned
)) {
94 return Err(NS_ERROR_OUT_OF_MEMORY
);
97 JS::Rooted
<JS::Value
> value(aCx
, JS::ObjectValue(*cloned
));
98 if (NS_WARN_IF(!aDest
.Init(aCx
, value
))) {
99 return Err(NS_ERROR_UNEXPECTED
);
105 * The following are utilities to convert between VideoColorSpace values to
109 gfx::ColorRange
ToColorRange(bool aIsFullRange
) {
110 return aIsFullRange
? gfx::ColorRange::FULL
: gfx::ColorRange::LIMITED
;
113 gfx::YUVColorSpace
ToColorSpace(VideoMatrixCoefficients aMatrix
) {
115 case VideoMatrixCoefficients::Rgb
:
116 return gfx::YUVColorSpace::Identity
;
117 case VideoMatrixCoefficients::Bt709
:
118 case VideoMatrixCoefficients::Bt470bg
:
119 return gfx::YUVColorSpace::BT709
;
120 case VideoMatrixCoefficients::Smpte170m
:
121 return gfx::YUVColorSpace::BT601
;
122 case VideoMatrixCoefficients::Bt2020_ncl
:
123 return gfx::YUVColorSpace::BT2020
;
124 case VideoMatrixCoefficients::EndGuard_
:
127 MOZ_ASSERT_UNREACHABLE("unsupported VideoMatrixCoefficients");
128 return gfx::YUVColorSpace::Default
;
131 gfx::TransferFunction
ToTransferFunction(
132 VideoTransferCharacteristics aTransfer
) {
134 case VideoTransferCharacteristics::Bt709
:
135 case VideoTransferCharacteristics::Smpte170m
:
136 return gfx::TransferFunction::BT709
;
137 case VideoTransferCharacteristics::Iec61966_2_1
:
138 return gfx::TransferFunction::SRGB
;
139 case VideoTransferCharacteristics::Pq
:
140 return gfx::TransferFunction::PQ
;
141 case VideoTransferCharacteristics::Hlg
:
142 return gfx::TransferFunction::HLG
;
143 case VideoTransferCharacteristics::Linear
:
144 case VideoTransferCharacteristics::EndGuard_
:
147 MOZ_ASSERT_UNREACHABLE("unsupported VideoTransferCharacteristics");
148 return gfx::TransferFunction::Default
;
151 gfx::ColorSpace2
ToPrimaries(VideoColorPrimaries aPrimaries
) {
152 switch (aPrimaries
) {
153 case VideoColorPrimaries::Bt709
:
154 return gfx::ColorSpace2::BT709
;
155 case VideoColorPrimaries::Bt470bg
:
156 return gfx::ColorSpace2::BT601_625
;
157 case VideoColorPrimaries::Smpte170m
:
158 return gfx::ColorSpace2::BT601_525
;
159 case VideoColorPrimaries::Bt2020
:
160 return gfx::ColorSpace2::BT2020
;
161 case VideoColorPrimaries::Smpte432
:
162 return gfx::ColorSpace2::DISPLAY_P3
;
163 case VideoColorPrimaries::EndGuard_
:
166 MOZ_ASSERT_UNREACHABLE("unsupported VideoTransferCharacteristics");
167 return gfx::ColorSpace2::UNKNOWN
;
170 bool ToFullRange(const gfx::ColorRange
& aColorRange
) {
171 return aColorRange
== gfx::ColorRange::FULL
;
174 Maybe
<VideoMatrixCoefficients
> ToMatrixCoefficients(
175 const gfx::YUVColorSpace
& aColorSpace
) {
176 switch (aColorSpace
) {
177 case gfx::YUVColorSpace::BT601
:
178 return Some(VideoMatrixCoefficients::Smpte170m
);
179 case gfx::YUVColorSpace::BT709
:
180 return Some(VideoMatrixCoefficients::Bt709
);
181 case gfx::YUVColorSpace::BT2020
:
182 return Some(VideoMatrixCoefficients::Bt2020_ncl
);
183 case gfx::YUVColorSpace::Identity
:
184 return Some(VideoMatrixCoefficients::Rgb
);
186 MOZ_ASSERT_UNREACHABLE("unsupported gfx::YUVColorSpace");
190 Maybe
<VideoTransferCharacteristics
> ToTransferCharacteristics(
191 const gfx::TransferFunction
& aTransferFunction
) {
192 switch (aTransferFunction
) {
193 case gfx::TransferFunction::BT709
:
194 return Some(VideoTransferCharacteristics::Bt709
);
195 case gfx::TransferFunction::SRGB
:
196 return Some(VideoTransferCharacteristics::Iec61966_2_1
);
197 case gfx::TransferFunction::PQ
:
198 return Some(VideoTransferCharacteristics::Pq
);
199 case gfx::TransferFunction::HLG
:
200 return Some(VideoTransferCharacteristics::Hlg
);
202 MOZ_ASSERT_UNREACHABLE("unsupported gfx::TransferFunction");
206 Maybe
<VideoColorPrimaries
> ToPrimaries(const gfx::ColorSpace2
& aColorSpace
) {
207 switch (aColorSpace
) {
208 case gfx::ColorSpace2::UNKNOWN
:
209 case gfx::ColorSpace2::SRGB
:
211 case gfx::ColorSpace2::DISPLAY_P3
:
212 return Some(VideoColorPrimaries::Smpte432
);
213 case gfx::ColorSpace2::BT601_525
:
214 return Some(VideoColorPrimaries::Smpte170m
);
215 case gfx::ColorSpace2::BT709
:
216 return Some(VideoColorPrimaries::Bt709
);
217 case gfx::ColorSpace2::BT2020
:
218 return Some(VideoColorPrimaries::Bt2020
);
220 MOZ_ASSERT_UNREACHABLE("unsupported gfx::ColorSpace2");
225 * The following are utilities to convert from gfx's formats to
229 Maybe
<VideoPixelFormat
> SurfaceFormatToVideoPixelFormat(
230 gfx::SurfaceFormat aFormat
) {
232 case gfx::SurfaceFormat::B8G8R8A8
:
233 return Some(VideoPixelFormat::BGRA
);
234 case gfx::SurfaceFormat::B8G8R8X8
:
235 return Some(VideoPixelFormat::BGRX
);
236 case gfx::SurfaceFormat::R8G8B8A8
:
237 return Some(VideoPixelFormat::RGBA
);
238 case gfx::SurfaceFormat::R8G8B8X8
:
239 return Some(VideoPixelFormat::RGBX
);
240 case gfx::SurfaceFormat::YUV
:
241 return Some(VideoPixelFormat::I420
);
242 case gfx::SurfaceFormat::NV12
:
243 return Some(VideoPixelFormat::NV12
);
244 case gfx::SurfaceFormat::YUV422
:
245 return Some(VideoPixelFormat::I422
);
252 Maybe
<VideoPixelFormat
> ImageBitmapFormatToVideoPixelFormat(
253 ImageBitmapFormat aFormat
) {
255 case ImageBitmapFormat::RGBA32
:
256 return Some(VideoPixelFormat::RGBA
);
257 case ImageBitmapFormat::BGRA32
:
258 return Some(VideoPixelFormat::BGRA
);
259 case ImageBitmapFormat::YUV444P
:
260 return Some(VideoPixelFormat::I444
);
261 case ImageBitmapFormat::YUV422P
:
262 return Some(VideoPixelFormat::I422
);
263 case ImageBitmapFormat::YUV420P
:
264 return Some(VideoPixelFormat::I420
);
265 case ImageBitmapFormat::YUV420SP_NV12
:
266 return Some(VideoPixelFormat::NV12
);
273 } // namespace mozilla::dom