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