Bug 1856663 - Add more chunks for Android mochitest-plain. r=jmaher,taskgraph-reviewe...
[gecko.git] / dom / media / webcodecs / WebCodecsUtils.cpp
blob9b3e23feb1800046c39c5e5473a1578a26c17a49
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"
17 #include "nsDebug.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};
42 return {};
46 * The below are helpers to operate ArrayBuffer or ArrayBufferView.
49 static std::tuple<JS::ArrayBufferOrView, size_t, size_t> GetArrayBufferInfo(
50 JSContext* aCx,
51 const OwningMaybeSharedArrayBufferViewOrMaybeSharedArrayBuffer& aBuffer) {
52 if (aBuffer.IsArrayBuffer()) {
53 const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
54 size_t length;
56 bool isShared;
57 uint8_t* data;
58 JS::GetArrayBufferMaybeSharedLengthAndData(buffer.Obj(), &length,
59 &isShared, &data);
61 return std::make_tuple(JS::ArrayBufferOrView::fromObject(buffer.Obj()),
62 (size_t)0, length);
65 MOZ_ASSERT(aBuffer.IsArrayBufferView());
66 const ArrayBufferView& view = aBuffer.GetAsArrayBufferView();
67 bool isSharedMemory;
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(
77 JSContext* aCx,
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);
101 return Ok();
105 * The following are utilities to convert between VideoColorSpace values to
106 * gfx's values.
109 gfx::ColorRange ToColorRange(bool aIsFullRange) {
110 return aIsFullRange ? gfx::ColorRange::FULL : gfx::ColorRange::LIMITED;
113 gfx::YUVColorSpace ToColorSpace(VideoMatrixCoefficients aMatrix) {
114 switch (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_:
125 break;
127 MOZ_ASSERT_UNREACHABLE("unsupported VideoMatrixCoefficients");
128 return gfx::YUVColorSpace::Default;
131 gfx::TransferFunction ToTransferFunction(
132 VideoTransferCharacteristics aTransfer) {
133 switch (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_:
145 break;
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_:
164 break;
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");
187 return Nothing();
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");
203 return Nothing();
206 Maybe<VideoColorPrimaries> ToPrimaries(const gfx::ColorSpace2& aColorSpace) {
207 switch (aColorSpace) {
208 case gfx::ColorSpace2::UNKNOWN:
209 case gfx::ColorSpace2::SRGB:
210 return Nothing();
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");
221 return Nothing();
225 * The following are utilities to convert from gfx's formats to
226 * VideoPixelFormats.
229 Maybe<VideoPixelFormat> SurfaceFormatToVideoPixelFormat(
230 gfx::SurfaceFormat aFormat) {
231 switch (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);
246 default:
247 break;
249 return Nothing();
252 Maybe<VideoPixelFormat> ImageBitmapFormatToVideoPixelFormat(
253 ImageBitmapFormat aFormat) {
254 switch (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);
267 default:
268 break;
270 return Nothing();
273 } // namespace mozilla::dom