1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "mozilla/ArrayUtils.h"
6 #include "mozilla/PodOperations.h"
7 #include "mozilla/ResultExtensions.h"
8 #include "BitReader.h"
9 #include "BufferReader.h"
10 #include "ByteWriter.h"
11 #include "AnnexB.h"
12 #include "H264.h"
13 #include <limits>
14 #include <cmath>
15
16 #define READSE(var, min, max) \
17 { \
18 int32_t val = br.ReadSE(); \
19 if (val < min || val > max) { \
20 return false; \
21 } \
22 aDest.var = val; \
23 }
24
25 #define READUE(var, max) \
26 { \
27 uint32_t uval = br.ReadUE(); \
28 if (uval > max) { \
29 return false; \
30 } \
31 aDest.var = uval; \
32 }
33
34 namespace mozilla {
35
36 // Default scaling lists (per spec).
37 // ITU H264:
38 // Table 7-2 – Assignment of mnemonic names to scaling list indices and
39 // specification of fall-back rule
40 static const uint8_t Default_4x4_Intra[16] = {6, 13, 13, 20, 20, 20, 28, 28,
41 28, 28, 32, 32, 32, 37, 37, 42};
42
43 static const uint8_t Default_4x4_Inter[16] = {10, 14, 14, 20, 20, 20, 24, 24,
44 24, 24, 27, 27, 27, 30, 30, 34};
45
46 static const uint8_t Default_8x8_Intra[64] = {
47 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
48 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
49 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
50 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42};
51
52 static const uint8_t Default_8x8_Inter[64] = {
53 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
54 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
55 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
56 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35};
57
58 namespace detail {
scaling_list(BitReader & aBr,uint8_t * aScalingList,int aSizeOfScalingList,const uint8_t * aDefaultList,const uint8_t * aFallbackList)59 static void scaling_list(BitReader& aBr, uint8_t* aScalingList,
60 int aSizeOfScalingList, const uint8_t* aDefaultList,
61 const uint8_t* aFallbackList) {
62 int32_t lastScale = 8;
63 int32_t nextScale = 8;
64 int32_t deltaScale;
65
66 // (pic|seq)_scaling_list_present_flag[i]
67 if (!aBr.ReadBit()) {
68 if (aFallbackList) {
69 memcpy(aScalingList, aFallbackList, aSizeOfScalingList);
70 }
71 return;
72 }
73
74 for (int i = 0; i < aSizeOfScalingList; i++) {
75 if (nextScale != 0) {
76 deltaScale = aBr.ReadSE();
77 nextScale = (lastScale + deltaScale + 256) % 256;
78 if (!i && !nextScale) {
79 memcpy(aScalingList, aDefaultList, aSizeOfScalingList);
80 return;
81 }
82 }
83 aScalingList[i] = (nextScale == 0) ? lastScale : nextScale;
84 lastScale = aScalingList[i];
85 }
86 }
87 } // namespace detail.
88
89 template <size_t N>
scaling_list(BitReader & aBr,uint8_t (& aScalingList)[N],const uint8_t (& aDefaultList)[N],const uint8_t (& aFallbackList)[N])90 static void scaling_list(BitReader& aBr, uint8_t (&aScalingList)[N],
91 const uint8_t (&aDefaultList)[N],
92 const uint8_t (&aFallbackList)[N]) {
93 detail::scaling_list(aBr, aScalingList, N, aDefaultList, aFallbackList);
94 }
95
96 template <size_t N>
scaling_list(BitReader & aBr,uint8_t (& aScalingList)[N],const uint8_t (& aDefaultList)[N])97 static void scaling_list(BitReader& aBr, uint8_t (&aScalingList)[N],
98 const uint8_t (&aDefaultList)[N]) {
99 detail::scaling_list(aBr, aScalingList, N, aDefaultList, nullptr);
100 }
101
GetBitLength(const mozilla::MediaByteBuffer * aNAL)102 static uint32_t GetBitLength(const mozilla::MediaByteBuffer* aNAL) {
103 size_t size = aNAL->Length();
104
105 while (size > 0 && aNAL->ElementAt(size - 1) == 0) {
106 size--;
107 }
108
109 if (!size) {
110 return 0;
111 }
112
113 if (size > UINT32_MAX / 8) {
114 // We can't represent it, we'll use as much as we can.
115 return UINT32_MAX;
116 }
117
118 uint8_t v = aNAL->ElementAt(size - 1);
119 size *= 8;
120
121 // Remove the stop bit and following trailing zeros.
122 if (v) {
123 // Count the consecutive zero bits (trailing) on the right by binary search.
124 // Adapted from Matt Whitlock algorithm to only bother with 8 bits integers.
125 uint32_t c;
126 if (v & 1) {
127 // Special case for odd v (assumed to happen half of the time).
128 c = 0;
129 } else {
130 c = 1;
131 if ((v & 0xf) == 0) {
132 v >>= 4;
133 c += 4;
134 }
135 if ((v & 0x3) == 0) {
136 v >>= 2;
137 c += 2;
138 }
139 c -= v & 0x1;
140 }
141 size -= c + 1;
142 }
143 return size;
144 }
145
SPSData()146 SPSData::SPSData() {
147 PodZero(this);
148 // Default values when they aren't defined as per ITU-T H.264 (2014/02).
149 chroma_format_idc = 1;
150 video_format = 5;
151 colour_primaries = 2;
152 transfer_characteristics = 2;
153 sample_ratio = 1.0;
154 memset(scaling_matrix4x4, 16, sizeof(scaling_matrix4x4));
155 memset(scaling_matrix8x8, 16, sizeof(scaling_matrix8x8));
156 }
157
operator ==(const SPSData & aOther) const158 bool SPSData::operator==(const SPSData& aOther) const {
159 return this->valid && aOther.valid && !memcmp(this, &aOther, sizeof(SPSData));
160 }
161
operator !=(const SPSData & aOther) const162 bool SPSData::operator!=(const SPSData& aOther) const {
163 return !(operator==(aOther));
164 }
165
166 // SPSNAL and SPSNALIterator do not own their data.
167 class SPSNAL {
168 public:
SPSNAL(const uint8_t * aPtr,size_t aLength)169 SPSNAL(const uint8_t* aPtr, size_t aLength) {
170 MOZ_ASSERT(aPtr);
171
172 if (aLength == 0 || (*aPtr & 0x1f) != H264_NAL_SPS) {
173 return;
174 }
175 mDecodedNAL = H264::DecodeNALUnit(aPtr, aLength);
176 if (mDecodedNAL) {
177 mLength = GetBitLength(mDecodedNAL);
178 }
179 }
180
SPSNAL()181 SPSNAL() {}
182
IsValid() const183 bool IsValid() const { return mDecodedNAL; }
184
operator ==(const SPSNAL & aOther) const185 bool operator==(const SPSNAL& aOther) const {
186 if (!mDecodedNAL || !aOther.mDecodedNAL) {
187 return false;
188 }
189
190 SPSData decodedSPS1;
191 SPSData decodedSPS2;
192 if (!GetSPSData(decodedSPS1) || !aOther.GetSPSData(decodedSPS2)) {
193 // Couldn't decode one SPS, perform a binary comparison
194 if (mLength != aOther.mLength) {
195 return false;
196 }
197 MOZ_ASSERT(mLength / 8 <= mDecodedNAL->Length());
198
199 if (memcmp(mDecodedNAL->Elements(), aOther.mDecodedNAL->Elements(),
200 mLength / 8)) {
201 return false;
202 }
203
204 uint32_t remaining = mLength - (mLength & ~7);
205
206 BitReader b1(mDecodedNAL->Elements() + mLength / 8, remaining);
207 BitReader b2(aOther.mDecodedNAL->Elements() + mLength / 8, remaining);
208 for (uint32_t i = 0; i < remaining; i++) {
209 if (b1.ReadBit() != b2.ReadBit()) {
210 return false;
211 }
212 }
213 return true;
214 }
215
216 return decodedSPS1 == decodedSPS2;
217 }
218
operator !=(const SPSNAL & aOther) const219 bool operator!=(const SPSNAL& aOther) const { return !(operator==(aOther)); }
220
GetSPSData(SPSData & aDest) const221 bool GetSPSData(SPSData& aDest) const {
222 return H264::DecodeSPS(mDecodedNAL, aDest);
223 }
224
225 private:
226 RefPtr<mozilla::MediaByteBuffer> mDecodedNAL;
227 uint32_t mLength = 0;
228 };
229
230 class SPSNALIterator {
231 public:
SPSNALIterator(const mozilla::MediaByteBuffer * aExtraData)232 explicit SPSNALIterator(const mozilla::MediaByteBuffer* aExtraData)
233 : mExtraDataPtr(aExtraData->Elements()), mReader(aExtraData) {
234 if (!mReader.Read(5)) {
235 return;
236 }
237
238 auto res = mReader.ReadU8();
239 mNumSPS = res.isOk() ? res.unwrap() & 0x1f : 0;
240 if (mNumSPS == 0) {
241 return;
242 }
243 mValid = true;
244 }
245
operator ++()246 SPSNALIterator& operator++() {
247 if (mEOS || !mValid) {
248 return *this;
249 }
250 if (--mNumSPS == 0) {
251 mEOS = true;
252 }
253 auto res = mReader.ReadU16();
254 uint16_t length = res.isOk() ? res.unwrap() : 0;
255 if (length == 0 || !mReader.Read(length)) {
256 mEOS = true;
257 }
258 return *this;
259 }
260
operator bool() const261 explicit operator bool() const { return mValid && !mEOS; }
262
operator *() const263 SPSNAL operator*() const {
264 MOZ_ASSERT(bool(*this));
265 BufferReader reader(mExtraDataPtr + mReader.Offset(), mReader.Remaining());
266
267 auto res = reader.ReadU16();
268 uint16_t length = res.isOk() ? res.unwrap() : 0;
269 const uint8_t* ptr = reader.Read(length);
270 if (!ptr || !length) {
271 return SPSNAL();
272 }
273 return SPSNAL(ptr, length);
274 }
275
276 private:
277 const uint8_t* mExtraDataPtr;
278 BufferReader mReader;
279 bool mValid = false;
280 bool mEOS = false;
281 uint8_t mNumSPS = 0;
282 };
283
DecodeNALUnit(const uint8_t * aNAL,size_t aLength)284 /* static */ already_AddRefed<mozilla::MediaByteBuffer> H264::DecodeNALUnit(
285 const uint8_t* aNAL, size_t aLength) {
286 MOZ_ASSERT(aNAL);
287
288 if (aLength < 4) {
289 return nullptr;
290 }
291
292 RefPtr<mozilla::MediaByteBuffer> rbsp = new mozilla::MediaByteBuffer;
293 BufferReader reader(aNAL, aLength);
294 auto res = reader.ReadU8();
295 if (res.isErr()) {
296 return nullptr;
297 }
298 uint8_t nal_unit_type = res.unwrap() & 0x1f;
299 uint32_t nalUnitHeaderBytes = 1;
300 if (nal_unit_type == H264_NAL_PREFIX || nal_unit_type == H264_NAL_SLICE_EXT ||
301 nal_unit_type == H264_NAL_SLICE_EXT_DVC) {
302 bool svc_extension_flag = false;
303 bool avc_3d_extension_flag = false;
304 if (nal_unit_type != H264_NAL_SLICE_EXT_DVC) {
305 res = reader.PeekU8();
306 if (res.isErr()) {
307 return nullptr;
308 }
309 svc_extension_flag = res.unwrap() & 0x80;
310 } else {
311 res = reader.PeekU8();
312 if (res.isErr()) {
313 return nullptr;
314 }
315 avc_3d_extension_flag = res.unwrap() & 0x80;
316 }
317 if (svc_extension_flag) {
318 nalUnitHeaderBytes += 3;
319 } else if (avc_3d_extension_flag) {
320 nalUnitHeaderBytes += 2;
321 } else {
322 nalUnitHeaderBytes += 3;
323 }
324 }
325 if (!reader.Read(nalUnitHeaderBytes - 1)) {
326 return nullptr;
327 }
328 uint32_t lastbytes = 0xffff;
329 while (reader.Remaining()) {
330 auto res = reader.ReadU8();
331 if (res.isErr()) {
332 return nullptr;
333 }
334 uint8_t byte = res.unwrap();
335 if ((lastbytes & 0xffff) == 0 && byte == 0x03) {
336 // reset last two bytes, to detect the 0x000003 sequence again.
337 lastbytes = 0xffff;
338 } else {
339 rbsp->AppendElement(byte);
340 }
341 lastbytes = (lastbytes << 8) | byte;
342 }
343 return rbsp.forget();
344 }
345
ConditionDimension(float aValue)346 static int32_t ConditionDimension(float aValue) {
347 // This will exclude NaNs and too-big values.
348 if (aValue > 1.0 && aValue <= INT32_MAX) return int32_t(aValue);
349 return 0;
350 }
351
DecodeSPS(const mozilla::MediaByteBuffer * aSPS,SPSData & aDest)352 /* static */ bool H264::DecodeSPS(const mozilla::MediaByteBuffer* aSPS,
353 SPSData& aDest) {
354 if (!aSPS) {
355 return false;
356 }
357 BitReader br(aSPS, GetBitLength(aSPS));
358
359 aDest.profile_idc = br.ReadBits(8);
360 aDest.constraint_set0_flag = br.ReadBit();
361 aDest.constraint_set1_flag = br.ReadBit();
362 aDest.constraint_set2_flag = br.ReadBit();
363 aDest.constraint_set3_flag = br.ReadBit();
364 aDest.constraint_set4_flag = br.ReadBit();
365 aDest.constraint_set5_flag = br.ReadBit();
366 br.ReadBits(2); // reserved_zero_2bits
367 aDest.level_idc = br.ReadBits(8);
368 READUE(seq_parameter_set_id, MAX_SPS_COUNT - 1);
369
370 if (aDest.profile_idc == 100 || aDest.profile_idc == 110 ||
371 aDest.profile_idc == 122 || aDest.profile_idc == 244 ||
372 aDest.profile_idc == 44 || aDest.profile_idc == 83 ||
373 aDest.profile_idc == 86 || aDest.profile_idc == 118 ||
374 aDest.profile_idc == 128 || aDest.profile_idc == 138 ||
375 aDest.profile_idc == 139 || aDest.profile_idc == 134) {
376 READUE(chroma_format_idc, 3);
377 if (aDest.chroma_format_idc == 3) {
378 aDest.separate_colour_plane_flag = br.ReadBit();
379 }
380 READUE(bit_depth_luma_minus8, 6);
381 READUE(bit_depth_chroma_minus8, 6);
382 br.ReadBit(); // qpprime_y_zero_transform_bypass_flag
383 aDest.seq_scaling_matrix_present_flag = br.ReadBit();
384 if (aDest.seq_scaling_matrix_present_flag) {
385 scaling_list(br, aDest.scaling_matrix4x4[0], Default_4x4_Intra,
386 Default_4x4_Intra);
387 scaling_list(br, aDest.scaling_matrix4x4[1], Default_4x4_Intra,
388 aDest.scaling_matrix4x4[0]);
389 scaling_list(br, aDest.scaling_matrix4x4[2], Default_4x4_Intra,
390 aDest.scaling_matrix4x4[1]);
391 scaling_list(br, aDest.scaling_matrix4x4[3], Default_4x4_Inter,
392 Default_4x4_Inter);
393 scaling_list(br, aDest.scaling_matrix4x4[4], Default_4x4_Inter,
394 aDest.scaling_matrix4x4[3]);
395 scaling_list(br, aDest.scaling_matrix4x4[5], Default_4x4_Inter,
396 aDest.scaling_matrix4x4[4]);
397
398 scaling_list(br, aDest.scaling_matrix8x8[0], Default_8x8_Intra,
399 Default_8x8_Intra);
400 scaling_list(br, aDest.scaling_matrix8x8[1], Default_8x8_Inter,
401 Default_8x8_Inter);
402 if (aDest.chroma_format_idc == 3) {
403 scaling_list(br, aDest.scaling_matrix8x8[2], Default_8x8_Intra,
404 aDest.scaling_matrix8x8[0]);
405 scaling_list(br, aDest.scaling_matrix8x8[3], Default_8x8_Inter,
406 aDest.scaling_matrix8x8[1]);
407 scaling_list(br, aDest.scaling_matrix8x8[4], Default_8x8_Intra,
408 aDest.scaling_matrix8x8[2]);
409 scaling_list(br, aDest.scaling_matrix8x8[5], Default_8x8_Inter,
410 aDest.scaling_matrix8x8[3]);
411 }
412 }
413 } else if (aDest.profile_idc == 183) {
414 aDest.chroma_format_idc = 0;
415 } else {
416 // default value if chroma_format_idc isn't set.
417 aDest.chroma_format_idc = 1;
418 }
419 READUE(log2_max_frame_num, 12);
420 aDest.log2_max_frame_num += 4;
421 READUE(pic_order_cnt_type, 2);
422 if (aDest.pic_order_cnt_type == 0) {
423 READUE(log2_max_pic_order_cnt_lsb, 12);
424 aDest.log2_max_pic_order_cnt_lsb += 4;
425 } else if (aDest.pic_order_cnt_type == 1) {
426 aDest.delta_pic_order_always_zero_flag = br.ReadBit();
427 READSE(offset_for_non_ref_pic, -231, 230);
428 READSE(offset_for_top_to_bottom_field, -231, 230);
429 uint32_t num_ref_frames_in_pic_order_cnt_cycle = br.ReadUE();
430 for (uint32_t i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++) {
431 br.ReadSE(); // offset_for_ref_frame[i]
432 }
433 }
434 aDest.max_num_ref_frames = br.ReadUE();
435 aDest.gaps_in_frame_num_allowed_flag = br.ReadBit();
436 aDest.pic_width_in_mbs = br.ReadUE() + 1;
437 aDest.pic_height_in_map_units = br.ReadUE() + 1;
438 aDest.frame_mbs_only_flag = br.ReadBit();
439 if (!aDest.frame_mbs_only_flag) {
440 aDest.pic_height_in_map_units *= 2;
441 aDest.mb_adaptive_frame_field_flag = br.ReadBit();
442 }
443 aDest.direct_8x8_inference_flag = br.ReadBit();
444 aDest.frame_cropping_flag = br.ReadBit();
445 if (aDest.frame_cropping_flag) {
446 aDest.frame_crop_left_offset = br.ReadUE();
447 aDest.frame_crop_right_offset = br.ReadUE();
448 aDest.frame_crop_top_offset = br.ReadUE();
449 aDest.frame_crop_bottom_offset = br.ReadUE();
450 }
451
452 aDest.sample_ratio = 1.0f;
453 aDest.vui_parameters_present_flag = br.ReadBit();
454 if (aDest.vui_parameters_present_flag) {
455 if (!vui_parameters(br, aDest)) {
456 return false;
457 }
458 }
459
460 // Calculate common values.
461
462 uint8_t ChromaArrayType =
463 aDest.separate_colour_plane_flag ? 0 : aDest.chroma_format_idc;
464 // Calculate width.
465 uint32_t CropUnitX = 1;
466 uint32_t SubWidthC = aDest.chroma_format_idc == 3 ? 1 : 2;
467 if (ChromaArrayType != 0) {
468 CropUnitX = SubWidthC;
469 }
470
471 // Calculate Height
472 uint32_t CropUnitY = 2 - aDest.frame_mbs_only_flag;
473 uint32_t SubHeightC = aDest.chroma_format_idc <= 1 ? 2 : 1;
474 if (ChromaArrayType != 0) {
475 CropUnitY *= SubHeightC;
476 }
477
478 uint32_t width = aDest.pic_width_in_mbs * 16;
479 uint32_t height = aDest.pic_height_in_map_units * 16;
480 if (aDest.frame_crop_left_offset <=
481 std::numeric_limits<int32_t>::max() / 4 / CropUnitX &&
482 aDest.frame_crop_right_offset <=
483 std::numeric_limits<int32_t>::max() / 4 / CropUnitX &&
484 aDest.frame_crop_top_offset <=
485 std::numeric_limits<int32_t>::max() / 4 / CropUnitY &&
486 aDest.frame_crop_bottom_offset <=
487 std::numeric_limits<int32_t>::max() / 4 / CropUnitY &&
488 (aDest.frame_crop_left_offset + aDest.frame_crop_right_offset) *
489 CropUnitX <
490 width &&
491 (aDest.frame_crop_top_offset + aDest.frame_crop_bottom_offset) *
492 CropUnitY <
493 height) {
494 aDest.crop_left = aDest.frame_crop_left_offset * CropUnitX;
495 aDest.crop_right = aDest.frame_crop_right_offset * CropUnitX;
496 aDest.crop_top = aDest.frame_crop_top_offset * CropUnitY;
497 aDest.crop_bottom = aDest.frame_crop_bottom_offset * CropUnitY;
498 } else {
499 // Nonsensical value, ignore them.
500 aDest.crop_left = aDest.crop_right = aDest.crop_top = aDest.crop_bottom = 0;
501 }
502
503 aDest.pic_width = width - aDest.crop_left - aDest.crop_right;
504 aDest.pic_height = height - aDest.crop_top - aDest.crop_bottom;
505
506 aDest.interlaced = !aDest.frame_mbs_only_flag;
507
508 // Determine display size.
509 if (aDest.sample_ratio > 1.0) {
510 // Increase the intrinsic width
511 aDest.display_width =
512 ConditionDimension(aDest.pic_width * aDest.sample_ratio);
513 aDest.display_height = aDest.pic_height;
514 } else {
515 // Increase the intrinsic height
516 aDest.display_width = aDest.pic_width;
517 aDest.display_height =
518 ConditionDimension(aDest.pic_height / aDest.sample_ratio);
519 }
520
521 aDest.valid = true;
522
523 return true;
524 }
525
vui_parameters(BitReader & aBr,SPSData & aDest)526 /* static */ bool H264::vui_parameters(BitReader& aBr, SPSData& aDest) {
527 aDest.aspect_ratio_info_present_flag = aBr.ReadBit();
528 if (aDest.aspect_ratio_info_present_flag) {
529 aDest.aspect_ratio_idc = aBr.ReadBits(8);
530 aDest.sar_width = aDest.sar_height = 0;
531
532 // From E.2.1 VUI parameters semantics (ITU-T H.264 02/2014)
533 switch (aDest.aspect_ratio_idc) {
534 case 0:
535 // Unspecified
536 break;
537 case 1:
538 /*
539 1:1
540 7680x4320 16:9 frame without horizontal overscan
541 3840x2160 16:9 frame without horizontal overscan
542 1280x720 16:9 frame without horizontal overscan
543 1920x1080 16:9 frame without horizontal overscan (cropped from
544 1920x1088) 640x480 4:3 frame without horizontal overscan
545 */
546 aDest.sample_ratio = 1.0f;
547 break;
548 case 2:
549 /*
550 12:11
551 720x576 4:3 frame with horizontal overscan
552 352x288 4:3 frame without horizontal overscan
553 */
554 aDest.sample_ratio = 12.0 / 11.0;
555 break;
556 case 3:
557 /*
558 10:11
559 720x480 4:3 frame with horizontal overscan
560 352x240 4:3 frame without horizontal overscan
561 */
562 aDest.sample_ratio = 10.0 / 11.0;
563 break;
564 case 4:
565 /*
566 16:11
567 720x576 16:9 frame with horizontal overscan
568 528x576 4:3 frame without horizontal overscan
569 */
570 aDest.sample_ratio = 16.0 / 11.0;
571 break;
572 case 5:
573 /*
574 40:33
575 720x480 16:9 frame with horizontal overscan
576 528x480 4:3 frame without horizontal overscan
577 */
578 aDest.sample_ratio = 40.0 / 33.0;
579 break;
580 case 6:
581 /*
582 24:11
583 352x576 4:3 frame without horizontal overscan
584 480x576 16:9 frame with horizontal overscan
585 */
586 aDest.sample_ratio = 24.0 / 11.0;
587 break;
588 case 7:
589 /*
590 20:11
591 352x480 4:3 frame without horizontal overscan
592 480x480 16:9 frame with horizontal overscan
593 */
594 aDest.sample_ratio = 20.0 / 11.0;
595 break;
596 case 8:
597 /*
598 32:11
599 352x576 16:9 frame without horizontal overscan
600 */
601 aDest.sample_ratio = 32.0 / 11.0;
602 break;
603 case 9:
604 /*
605 80:33
606 352x480 16:9 frame without horizontal overscan
607 */
608 aDest.sample_ratio = 80.0 / 33.0;
609 break;
610 case 10:
611 /*
612 18:11
613 480x576 4:3 frame with horizontal overscan
614 */
615 aDest.sample_ratio = 18.0 / 11.0;
616 break;
617 case 11:
618 /*
619 15:11
620 480x480 4:3 frame with horizontal overscan
621 */
622 aDest.sample_ratio = 15.0 / 11.0;
623 break;
624 case 12:
625 /*
626 64:33
627 528x576 16:9 frame with horizontal overscan
628 */
629 aDest.sample_ratio = 64.0 / 33.0;
630 break;
631 case 13:
632 /*
633 160:99
634 528x480 16:9 frame without horizontal overscan
635 */
636 aDest.sample_ratio = 160.0 / 99.0;
637 break;
638 case 14:
639 /*
640 4:3
641 1440x1080 16:9 frame without horizontal overscan
642 */
643 aDest.sample_ratio = 4.0 / 3.0;
644 break;
645 case 15:
646 /*
647 3:2
648 1280x1080 16:9 frame without horizontal overscan
649 */
650 aDest.sample_ratio = 3.2 / 2.0;
651 break;
652 case 16:
653 /*
654 2:1
655 960x1080 16:9 frame without horizontal overscan
656 */
657 aDest.sample_ratio = 2.0 / 1.0;
658 break;
659 case 255:
660 /* Extended_SAR */
661 aDest.sar_width = aBr.ReadBits(16);
662 aDest.sar_height = aBr.ReadBits(16);
663 if (aDest.sar_width && aDest.sar_height) {
664 aDest.sample_ratio = float(aDest.sar_width) / float(aDest.sar_height);
665 }
666 break;
667 default:
668 break;
669 }
670 }
671
672 if (aBr.ReadBit()) { // overscan_info_present_flag
673 aDest.overscan_appropriate_flag = aBr.ReadBit();
674 }
675
676 if (aBr.ReadBit()) { // video_signal_type_present_flag
677 aDest.video_format = aBr.ReadBits(3);
678 aDest.video_full_range_flag = aBr.ReadBit();
679 aDest.colour_description_present_flag = aBr.ReadBit();
680 if (aDest.colour_description_present_flag) {
681 aDest.colour_primaries = aBr.ReadBits(8);
682 aDest.transfer_characteristics = aBr.ReadBits(8);
683 aDest.matrix_coefficients = aBr.ReadBits(8);
684 }
685 }
686
687 aDest.chroma_loc_info_present_flag = aBr.ReadBit();
688 if (aDest.chroma_loc_info_present_flag) {
689 BitReader& br = aBr; // so that macro READUE works
690 READUE(chroma_sample_loc_type_top_field, 5);
691 READUE(chroma_sample_loc_type_bottom_field, 5);
692 }
693
694 bool timing_info_present_flag = aBr.ReadBit();
695 if (timing_info_present_flag) {
696 aBr.ReadBits(32); // num_units_in_tick
697 aBr.ReadBits(32); // time_scale
698 aBr.ReadBit(); // fixed_frame_rate_flag
699 }
700 return true;
701 }
702
DecodeSPSFromExtraData(const mozilla::MediaByteBuffer * aExtraData,SPSData & aDest)703 /* static */ bool H264::DecodeSPSFromExtraData(
704 const mozilla::MediaByteBuffer* aExtraData, SPSData& aDest) {
705 SPSNALIterator it(aExtraData);
706 if (!it) {
707 return false;
708 }
709 return (*it).GetSPSData(aDest);
710 }
711
EnsureSPSIsSane(SPSData & aSPS)712 /* static */ bool H264::EnsureSPSIsSane(SPSData& aSPS) {
713 bool valid = true;
714 static const float default_aspect = 4.0f / 3.0f;
715 if (aSPS.sample_ratio <= 0.0f || aSPS.sample_ratio > 6.0f) {
716 if (aSPS.pic_width && aSPS.pic_height) {
717 aSPS.sample_ratio = (float)aSPS.pic_width / (float)aSPS.pic_height;
718 } else {
719 aSPS.sample_ratio = default_aspect;
720 }
721 aSPS.display_width = aSPS.pic_width;
722 aSPS.display_height = aSPS.pic_height;
723 valid = false;
724 }
725 if (aSPS.max_num_ref_frames > 16) {
726 aSPS.max_num_ref_frames = 16;
727 valid = false;
728 }
729 return valid;
730 }
731
ComputeMaxRefFrames(const mozilla::MediaByteBuffer * aExtraData)732 /* static */ uint32_t H264::ComputeMaxRefFrames(
733 const mozilla::MediaByteBuffer* aExtraData) {
734 uint32_t maxRefFrames = 4;
735 // Retrieve video dimensions from H264 SPS NAL.
736 SPSData spsdata;
737 if (DecodeSPSFromExtraData(aExtraData, spsdata)) {
738 // max_num_ref_frames determines the size of the sliding window
739 // we need to queue that many frames in order to guarantee proper
740 // pts frames ordering. Use a minimum of 4 to ensure proper playback of
741 // non compliant videos.
742 maxRefFrames =
743 std::min(std::max(maxRefFrames, spsdata.max_num_ref_frames + 1), 16u);
744 }
745 return maxRefFrames;
746 }
747
GetFrameType(const mozilla::MediaRawData * aSample)748 /* static */ H264::FrameType H264::GetFrameType(
749 const mozilla::MediaRawData* aSample) {
750 if (!AnnexB::IsAVCC(aSample)) {
751 // We must have a valid AVCC frame with extradata.
752 return FrameType::INVALID;
753 }
754 MOZ_ASSERT(aSample->Data());
755
756 int nalLenSize = ((*aSample->mExtraData)[4] & 3) + 1;
757
758 BufferReader reader(aSample->Data(), aSample->Size());
759
760 while (reader.Remaining() >= nalLenSize) {
761 uint32_t nalLen = 0;
762 switch (nalLenSize) {
763 case 1:
764 nalLen = reader.ReadU8().unwrapOr(0);
765 break;
766 case 2:
767 nalLen = reader.ReadU16().unwrapOr(0);
768 break;
769 case 3:
770 nalLen = reader.ReadU24().unwrapOr(0);
771 break;
772 case 4:
773 nalLen = reader.ReadU32().unwrapOr(0);
774 break;
775 }
776 if (!nalLen) {
777 continue;
778 }
779 const uint8_t* p = reader.Read(nalLen);
780 if (!p) {
781 return FrameType::INVALID;
782 }
783 int8_t nalType = *p & 0x1f;
784 if (nalType == H264_NAL_IDR_SLICE) {
785 // IDR NAL.
786 return FrameType::I_FRAME;
787 } else if (nalType == H264_NAL_SEI) {
788 RefPtr<mozilla::MediaByteBuffer> decodedNAL = DecodeNALUnit(p, nalLen);
789 SEIRecoveryData data;
790 if (DecodeRecoverySEI(decodedNAL, data)) {
791 return FrameType::I_FRAME;
792 }
793 }
794 }
795
796 return FrameType::OTHER;
797 }
798
ExtractExtraData(const mozilla::MediaRawData * aSample)799 /* static */ already_AddRefed<mozilla::MediaByteBuffer> H264::ExtractExtraData(
800 const mozilla::MediaRawData* aSample) {
801 MOZ_ASSERT(AnnexB::IsAVCC(aSample));
802
803 RefPtr<mozilla::MediaByteBuffer> extradata = new mozilla::MediaByteBuffer;
804
805 // SPS content
806 nsTArray<uint8_t> sps;
807 ByteWriter spsw(sps);
808 int numSps = 0;
809 // PPS content
810 nsTArray<uint8_t> pps;
811 ByteWriter ppsw(pps);
812 int numPps = 0;
813
814 int nalLenSize = ((*aSample->mExtraData)[4] & 3) + 1;
815
816 size_t sampleSize = aSample->Size();
817 if (aSample->mCrypto.mValid) {
818 // The content is encrypted, we can only parse the non-encrypted data.
819 MOZ_ASSERT(aSample->mCrypto.mPlainSizes.Length() > 0);
820 if (aSample->mCrypto.mPlainSizes.Length() == 0 ||
821 aSample->mCrypto.mPlainSizes[0] > sampleSize) {
822 // This is invalid content.
823 return nullptr;
824 }
825 sampleSize = aSample->mCrypto.mPlainSizes[0];
826 }
827
828 BufferReader reader(aSample->Data(), sampleSize);
829
830 nsTArray<SPSData> SPSTable;
831 // If we encounter SPS with the same id but different content, we will stop
832 // attempting to detect duplicates.
833 bool checkDuplicate = true;
834
835 // Find SPS and PPS NALUs in AVCC data
836 while (reader.Remaining() > nalLenSize) {
837 uint32_t nalLen = 0;
838 switch (nalLenSize) {
839 case 1:
840 Unused << reader.ReadU8().map(
841 [&](uint8_t x) mutable { return nalLen = x; });
842 break;
843 case 2:
844 Unused << reader.ReadU16().map(
845 [&](uint16_t x) mutable { return nalLen = x; });
846 break;
847 case 3:
848 Unused << reader.ReadU24().map(
849 [&](uint32_t x) mutable { return nalLen = x; });
850 break;
851 case 4:
852 Unused << reader.ReadU32().map(
853 [&](uint32_t x) mutable { return nalLen = x; });
854 break;
855 }
856 const uint8_t* p = reader.Read(nalLen);
857 if (!p) {
858 return extradata.forget();
859 }
860 uint8_t nalType = *p & 0x1f;
861
862 if (nalType == H264_NAL_SPS) {
863 RefPtr<mozilla::MediaByteBuffer> sps = DecodeNALUnit(p, nalLen);
864 SPSData data;
865 if (!DecodeSPS(sps, data)) {
866 // Invalid SPS, ignore.
867 continue;
868 }
869 uint8_t spsId = data.seq_parameter_set_id;
870 if (spsId >= SPSTable.Length()) {
871 if (!SPSTable.SetLength(spsId + 1, fallible)) {
872 // OOM.
873 return nullptr;
874 }
875 }
876 if (checkDuplicate && SPSTable[spsId].valid && SPSTable[spsId] == data) {
877 // Duplicate ignore.
878 continue;
879 }
880 if (SPSTable[spsId].valid) {
881 // We already have detected a SPS with this Id. Just to be safe we
882 // disable SPS duplicate detection.
883 checkDuplicate = false;
884 } else {
885 SPSTable[spsId] = data;
886 }
887 numSps++;
888 if (!spsw.WriteU16(nalLen) || !spsw.Write(p, nalLen)) {
889 return extradata.forget();
890 }
891 } else if (nalType == H264_NAL_PPS) {
892 numPps++;
893 if (!ppsw.WriteU16(nalLen) || !ppsw.Write(p, nalLen)) {
894 return extradata.forget();
895 }
896 }
897 }
898
899 // We ignore PPS data if we didn't find a SPS as we would be unable to
900 // decode it anyway.
901 numPps = numSps ? numPps : 0;
902
903 if (numSps && sps.Length() > 5) {
904 extradata->AppendElement(1); // version
905 extradata->AppendElement(sps[3]); // profile
906 extradata->AppendElement(sps[4]); // profile compat
907 extradata->AppendElement(sps[5]); // level
908 extradata->AppendElement(0xfc | 3); // nal size - 1
909 extradata->AppendElement(0xe0 | numSps);
910 extradata->AppendElements(sps.Elements(), sps.Length());
911 extradata->AppendElement(numPps);
912 if (numPps) {
913 extradata->AppendElements(pps.Elements(), pps.Length());
914 }
915 }
916
917 return extradata.forget();
918 }
919
HasSPS(const mozilla::MediaByteBuffer * aExtraData)920 /* static */ bool H264::HasSPS(const mozilla::MediaByteBuffer* aExtraData) {
921 return NumSPS(aExtraData) > 0;
922 }
923
NumSPS(const mozilla::MediaByteBuffer * aExtraData)924 /* static */ uint8_t H264::NumSPS(const mozilla::MediaByteBuffer* aExtraData) {
925 if (!aExtraData || aExtraData->IsEmpty()) {
926 return 0;
927 }
928
929 BufferReader reader(aExtraData);
930 if (!reader.Read(5)) {
931 return 0;
932 }
933 auto res = reader.ReadU8();
934 if (res.isErr()) {
935 return 0;
936 }
937 return res.unwrap() & 0x1f;
938 }
939
CompareExtraData(const mozilla::MediaByteBuffer * aExtraData1,const mozilla::MediaByteBuffer * aExtraData2)940 /* static */ bool H264::CompareExtraData(
941 const mozilla::MediaByteBuffer* aExtraData1,
942 const mozilla::MediaByteBuffer* aExtraData2) {
943 if (aExtraData1 == aExtraData2) {
944 return true;
945 }
946 uint8_t numSPS = NumSPS(aExtraData1);
947 if (numSPS == 0 || numSPS != NumSPS(aExtraData2)) {
948 return false;
949 }
950
951 // We only compare if the SPS are the same as the various H264 decoders can
952 // deal with in-band change of PPS.
953
954 SPSNALIterator it1(aExtraData1);
955 SPSNALIterator it2(aExtraData2);
956
957 while (it1 && it2) {
958 if (*it1 != *it2) {
959 return false;
960 }
961 ++it1;
962 ++it2;
963 }
964 return true;
965 }
966
ReadSEIInt(BufferReader & aBr,uint32_t & aOutput)967 static inline Result<Ok, nsresult> ReadSEIInt(BufferReader& aBr,
968 uint32_t& aOutput) {
969 uint8_t tmpByte;
970
971 aOutput = 0;
972 MOZ_TRY_VAR(tmpByte, aBr.ReadU8());
973 while (tmpByte == 0xFF) {
974 aOutput += 255;
975 MOZ_TRY_VAR(tmpByte, aBr.ReadU8());
976 }
977 aOutput += tmpByte; // this is the last byte
978 return Ok();
979 }
980
DecodeRecoverySEI(const mozilla::MediaByteBuffer * aSEI,SEIRecoveryData & aDest)981 /* static */ bool H264::DecodeRecoverySEI(const mozilla::MediaByteBuffer* aSEI,
982 SEIRecoveryData& aDest) {
983 if (!aSEI) {
984 return false;
985 }
986 // sei_rbsp() as per 7.3.2.3 Supplemental enhancement information RBSP syntax
987 BufferReader br(aSEI);
988
989 do {
990 // sei_message() as per
991 // 7.3.2.3.1 Supplemental enhancement information message syntax
992 uint32_t payloadType = 0;
993 if (ReadSEIInt(br, payloadType).isErr()) {
994 return false;
995 }
996
997 uint32_t payloadSize = 0;
998 if (ReadSEIInt(br, payloadSize).isErr()) {
999 return false;
1000 }
1001
1002 // sei_payload(payloadType, payloadSize) as per
1003 // D.1 SEI payload syntax.
1004 const uint8_t* p = br.Read(payloadSize);
1005 if (!p) {
1006 return false;
1007 }
1008 if (payloadType == 6) { // SEI_RECOVERY_POINT
1009 if (payloadSize == 0) {
1010 // Invalid content, ignore.
1011 continue;
1012 }
1013 // D.1.7 Recovery point SEI message syntax
1014 BitReader br(p, payloadSize * 8);
1015 aDest.recovery_frame_cnt = br.ReadUE();
1016 aDest.exact_match_flag = br.ReadBit();
1017 aDest.broken_link_flag = br.ReadBit();
1018 aDest.changing_slice_group_idc = br.ReadBits(2);
1019 return true;
1020 }
1021 } while (br.PeekU8().isOk() &&
1022 br.PeekU8().unwrap() !=
1023 0x80); // more_rbsp_data() msg[offset] != 0x80
1024 // ignore the trailing bits rbsp_trailing_bits();
1025 return false;
1026 }
1027
1028 #undef READUE
1029 #undef READSE
1030
1031 } // namespace mozilla
1032