1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 // Note: ported from Chromium commit head: 2de6929
5
6 #include "h264_parser.h"
7 #include "subsample_entry.h"
8
9 #include <limits>
10 #include <memory>
11
12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "base/numerics/safe_math.h"
15
16 namespace media {
17
IsPSlice() const18 bool H264SliceHeader::IsPSlice() const {
19 return (slice_type % 5 == kPSlice);
20 }
21
IsBSlice() const22 bool H264SliceHeader::IsBSlice() const {
23 return (slice_type % 5 == kBSlice);
24 }
25
IsISlice() const26 bool H264SliceHeader::IsISlice() const {
27 return (slice_type % 5 == kISlice);
28 }
29
IsSPSlice() const30 bool H264SliceHeader::IsSPSlice() const {
31 return (slice_type % 5 == kSPSlice);
32 }
33
IsSISlice() const34 bool H264SliceHeader::IsSISlice() const {
35 return (slice_type % 5 == kSISlice);
36 }
37
H264NALU()38 H264NALU::H264NALU() {
39 memset(this, 0, sizeof(*this));
40 }
41
H264SPS()42 H264SPS::H264SPS() {
43 memset(this, 0, sizeof(*this));
44 }
45
46 // Based on T-REC-H.264 7.4.2.1.1, "Sequence parameter set data semantics",
47 // available from http://www.itu.int/rec/T-REC-H.264.
GetCodedSize() const48 base::Optional<Size> H264SPS::GetCodedSize() const {
49 // Interlaced frames are twice the height of each field.
50 const int mb_unit = 16;
51 int map_unit = frame_mbs_only_flag ? 16 : 32;
52
53 // Verify that the values are not too large before multiplying them.
54 // TODO(sandersd): These limits could be much smaller. The currently-largest
55 // specified limit (excluding SVC, multiview, etc., which I didn't bother to
56 // read) is 543 macroblocks (section A.3.1).
57 int max_mb_minus1 = std::numeric_limits<int>::max() / mb_unit - 1;
58 int max_map_units_minus1 = std::numeric_limits<int>::max() / map_unit - 1;
59 if (pic_width_in_mbs_minus1 > max_mb_minus1 ||
60 pic_height_in_map_units_minus1 > max_map_units_minus1) {
61 DVLOG(1) << "Coded size is too large.";
62 return base::nullopt;
63 }
64
65 return Size(mb_unit * (pic_width_in_mbs_minus1 + 1),
66 map_unit * (pic_height_in_map_units_minus1 + 1));
67 }
68
69 // Also based on section 7.4.2.1.1.
GetVisibleRect() const70 base::Optional<Rect> H264SPS::GetVisibleRect() const {
71 base::Optional<Size> coded_size = GetCodedSize();
72 if (!coded_size)
73 return base::nullopt;
74
75 if (!frame_cropping_flag)
76 return Rect(coded_size.value());
77
78 int crop_unit_x;
79 int crop_unit_y;
80 if (chroma_array_type == 0) {
81 crop_unit_x = 1;
82 crop_unit_y = frame_mbs_only_flag ? 1 : 2;
83 } else {
84 // Section 6.2.
85 // |chroma_format_idc| may be:
86 // 1 => 4:2:0
87 // 2 => 4:2:2
88 // 3 => 4:4:4
89 // Everything else has |chroma_array_type| == 0.
90 int sub_width_c = chroma_format_idc > 2 ? 1 : 2;
91 int sub_height_c = chroma_format_idc > 1 ? 1 : 2;
92 crop_unit_x = sub_width_c;
93 crop_unit_y = sub_height_c * (frame_mbs_only_flag ? 1 : 2);
94 }
95
96 // Verify that the values are not too large before multiplying.
97 if (coded_size->width() / crop_unit_x < frame_crop_left_offset ||
98 coded_size->width() / crop_unit_x < frame_crop_right_offset ||
99 coded_size->height() / crop_unit_y < frame_crop_top_offset ||
100 coded_size->height() / crop_unit_y < frame_crop_bottom_offset) {
101 DVLOG(1) << "Frame cropping exceeds coded size.";
102 return base::nullopt;
103 }
104 int crop_left = crop_unit_x * frame_crop_left_offset;
105 int crop_right = crop_unit_x * frame_crop_right_offset;
106 int crop_top = crop_unit_y * frame_crop_top_offset;
107 int crop_bottom = crop_unit_y * frame_crop_bottom_offset;
108
109 // Verify that the values are sane. Note that some decoders also require that
110 // crops are smaller than a macroblock and/or that crops must be adjacent to
111 // at least one corner of the coded frame.
112 if (coded_size->width() - crop_left <= crop_right ||
113 coded_size->height() - crop_top <= crop_bottom) {
114 DVLOG(1) << "Frame cropping excludes entire frame.";
115 return base::nullopt;
116 }
117
118 return Rect(crop_left, crop_top,
119 coded_size->width() - crop_left - crop_right,
120 coded_size->height() - crop_top - crop_bottom);
121 }
122
H264PPS()123 H264PPS::H264PPS() {
124 memset(this, 0, sizeof(*this));
125 }
126
H264SliceHeader()127 H264SliceHeader::H264SliceHeader() {
128 memset(this, 0, sizeof(*this));
129 }
130
H264SEIMessage()131 H264SEIMessage::H264SEIMessage() {
132 memset(this, 0, sizeof(*this));
133 }
134
135 #define READ_BITS_OR_RETURN(num_bits, out) \
136 do { \
137 int _out; \
138 if (!br_.ReadBits(num_bits, &_out)) { \
139 DVLOG(1) \
140 << "Error in stream: unexpected EOS while trying to read " #out; \
141 return kInvalidStream; \
142 } \
143 *out = _out; \
144 } while (0)
145
146 #define READ_BOOL_OR_RETURN(out) \
147 do { \
148 int _out; \
149 if (!br_.ReadBits(1, &_out)) { \
150 DVLOG(1) \
151 << "Error in stream: unexpected EOS while trying to read " #out; \
152 return kInvalidStream; \
153 } \
154 *out = _out != 0; \
155 } while (0)
156
157 #define READ_UE_OR_RETURN(out) \
158 do { \
159 if (ReadUE(out) != kOk) { \
160 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
161 return kInvalidStream; \
162 } \
163 } while (0)
164
165 #define READ_SE_OR_RETURN(out) \
166 do { \
167 if (ReadSE(out) != kOk) { \
168 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
169 return kInvalidStream; \
170 } \
171 } while (0)
172
173 #define IN_RANGE_OR_RETURN(val, min, max) \
174 do { \
175 if ((val) < (min) || (val) > (max)) { \
176 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
177 << " in range [" << (min) << ":" << (max) << "]" \
178 << " found " << (val) << " instead"; \
179 return kInvalidStream; \
180 } \
181 } while (0)
182
183 #define TRUE_OR_RETURN(a) \
184 do { \
185 if (!(a)) { \
186 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
187 return kInvalidStream; \
188 } \
189 } while (0)
190
191 // ISO 14496 part 10
192 // VUI parameters: Table E-1 "Meaning of sample aspect ratio indicator"
193 static const int kTableSarWidth[] = {0, 1, 12, 10, 16, 40, 24, 20, 32,
194 80, 18, 15, 64, 160, 4, 3, 2};
195 static const int kTableSarHeight[] = {0, 1, 11, 11, 11, 33, 11, 11, 11,
196 33, 11, 11, 33, 99, 3, 2, 1};
197 static_assert(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
198 "sar tables must have the same size");
199
H264Parser()200 H264Parser::H264Parser() {
201 Reset();
202 }
203
204 H264Parser::~H264Parser() = default;
205
Reset()206 void H264Parser::Reset() {
207 stream_ = NULL;
208 bytes_left_ = 0;
209 encrypted_ranges_.clear();
210 }
211
SetStream(const uint8_t * stream,off_t stream_size)212 void H264Parser::SetStream(const uint8_t* stream, off_t stream_size) {
213 std::vector<SubsampleEntry> subsamples;
214 SetEncryptedStream(stream, stream_size, subsamples);
215 }
216
SetEncryptedStream(const uint8_t * stream,off_t stream_size,const std::vector<SubsampleEntry> & subsamples)217 void H264Parser::SetEncryptedStream(
218 const uint8_t* stream,
219 off_t stream_size,
220 const std::vector<SubsampleEntry>& subsamples) {
221 DCHECK(stream);
222 DCHECK_GT(stream_size, 0);
223
224 stream_ = stream;
225 bytes_left_ = stream_size;
226
227 encrypted_ranges_.clear();
228 const uint8_t* start = stream;
229 const uint8_t* stream_end = stream_ + bytes_left_;
230 for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) {
231 start += subsamples[i].clear_bytes;
232
233 const uint8_t* end =
234 std::min(start + subsamples[i].cypher_bytes, stream_end);
235 encrypted_ranges_.Add(start, end);
236 start = end;
237 }
238 }
239
GetPPS(int pps_id) const240 const H264PPS* H264Parser::GetPPS(int pps_id) const {
241 auto it = active_PPSes_.find(pps_id);
242 if (it == active_PPSes_.end()) {
243 DVLOG(1) << "Requested a nonexistent PPS id " << pps_id;
244 return nullptr;
245 }
246
247 return it->second.get();
248 }
249
GetSPS(int sps_id) const250 const H264SPS* H264Parser::GetSPS(int sps_id) const {
251 auto it = active_SPSes_.find(sps_id);
252 if (it == active_SPSes_.end()) {
253 DVLOG(1) << "Requested a nonexistent SPS id " << sps_id;
254 return nullptr;
255 }
256
257 return it->second.get();
258 }
259
IsStartCode(const uint8_t * data)260 static inline bool IsStartCode(const uint8_t* data) {
261 return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01;
262 }
263
264 // static
FindStartCode(const uint8_t * data,off_t data_size,off_t * offset,off_t * start_code_size)265 bool H264Parser::FindStartCode(const uint8_t* data,
266 off_t data_size,
267 off_t* offset,
268 off_t* start_code_size) {
269 DCHECK_GE(data_size, 0);
270 off_t bytes_left = data_size;
271
272 while (bytes_left >= 3) {
273 // The start code is "\0\0\1", ones are more unusual than zeroes, so let's
274 // search for it first.
275 const uint8_t* tmp =
276 reinterpret_cast<const uint8_t*>(memchr(data + 2, 1, bytes_left - 2));
277 if (!tmp) {
278 data += bytes_left - 2;
279 bytes_left = 2;
280 break;
281 }
282 tmp -= 2;
283 bytes_left -= tmp - data;
284 data = tmp;
285
286 if (IsStartCode(data)) {
287 // Found three-byte start code, set pointer at its beginning.
288 *offset = data_size - bytes_left;
289 *start_code_size = 3;
290
291 // If there is a zero byte before this start code,
292 // then it's actually a four-byte start code, so backtrack one byte.
293 if (*offset > 0 && *(data - 1) == 0x00) {
294 --(*offset);
295 ++(*start_code_size);
296 }
297
298 return true;
299 }
300
301 ++data;
302 --bytes_left;
303 }
304
305 // End of data: offset is pointing to the first byte that was not considered
306 // as a possible start of a start code.
307 // Note: there is no security issue when receiving a negative |data_size|
308 // since in this case, |bytes_left| is equal to |data_size| and thus
309 // |*offset| is equal to 0 (valid offset).
310 *offset = data_size - bytes_left;
311 *start_code_size = 0;
312 return false;
313 }
314
LocateNALU(off_t * nalu_size,off_t * start_code_size)315 bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) {
316 // Find the start code of next NALU.
317 off_t nalu_start_off = 0;
318 off_t annexb_start_code_size = 0;
319
320 if (!FindStartCodeInClearRanges(stream_, bytes_left_, encrypted_ranges_,
321 &nalu_start_off, &annexb_start_code_size)) {
322 DVLOG(4) << "Could not find start code, end of stream?";
323 return false;
324 }
325
326 // Move the stream to the beginning of the NALU (pointing at the start code).
327 stream_ += nalu_start_off;
328 bytes_left_ -= nalu_start_off;
329
330 const uint8_t* nalu_data = stream_ + annexb_start_code_size;
331 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size;
332 if (max_nalu_data_size <= 0) {
333 DVLOG(3) << "End of stream";
334 return false;
335 }
336
337 // Find the start code of next NALU;
338 // if successful, |nalu_size_without_start_code| is the number of bytes from
339 // after previous start code to before this one;
340 // if next start code is not found, it is still a valid NALU since there
341 // are some bytes left after the first start code: all the remaining bytes
342 // belong to the current NALU.
343 off_t next_start_code_size = 0;
344 off_t nalu_size_without_start_code = 0;
345 if (!FindStartCodeInClearRanges(
346 nalu_data, max_nalu_data_size, encrypted_ranges_,
347 &nalu_size_without_start_code, &next_start_code_size)) {
348 nalu_size_without_start_code = max_nalu_data_size;
349 }
350 *nalu_size = nalu_size_without_start_code + annexb_start_code_size;
351 *start_code_size = annexb_start_code_size;
352 return true;
353 }
354
355 // static
FindStartCodeInClearRanges(const uint8_t * data,off_t data_size,const Ranges<const uint8_t * > & encrypted_ranges,off_t * offset,off_t * start_code_size)356 bool H264Parser::FindStartCodeInClearRanges(
357 const uint8_t* data,
358 off_t data_size,
359 const Ranges<const uint8_t*>& encrypted_ranges,
360 off_t* offset,
361 off_t* start_code_size) {
362 if (encrypted_ranges.size() == 0)
363 return FindStartCode(data, data_size, offset, start_code_size);
364
365 DCHECK_GE(data_size, 0);
366 const uint8_t* start = data;
367 do {
368 off_t bytes_left = data_size - (start - data);
369
370 if (!FindStartCode(start, bytes_left, offset, start_code_size))
371 return false;
372
373 // Construct a Ranges object that represents the region occupied
374 // by the start code and the 1 byte needed to read the NAL unit type.
375 const uint8_t* start_code = start + *offset;
376 const uint8_t* start_code_end = start_code + *start_code_size;
377 Ranges<const uint8_t*> start_code_range;
378 start_code_range.Add(start_code, start_code_end + 1);
379
380 if (encrypted_ranges.IntersectionWith(start_code_range).size() > 0) {
381 // The start code is inside an encrypted section so we need to scan
382 // for another start code.
383 *start_code_size = 0;
384 start += std::min(*offset + 1, bytes_left);
385 }
386 } while (*start_code_size == 0);
387
388 // Update |*offset| to include the data we skipped over.
389 *offset += start - data;
390 return true;
391 }
392
393 // static
ParseNALUs(const uint8_t * stream,size_t stream_size,std::vector<H264NALU> * nalus)394 bool H264Parser::ParseNALUs(const uint8_t* stream,
395 size_t stream_size,
396 std::vector<H264NALU>* nalus) {
397 DCHECK(nalus);
398 H264Parser parser;
399 parser.SetStream(stream, stream_size);
400
401 while (true) {
402 H264NALU nalu;
403 const H264Parser::Result result = parser.AdvanceToNextNALU(&nalu);
404 if (result == H264Parser::kOk) {
405 nalus->push_back(nalu);
406 } else if (result == media::H264Parser::kEOStream) {
407 return true;
408 } else {
409 DLOG(ERROR) << "Unexpected H264 parser result";
410 return false;
411 }
412 }
413 NOTREACHED();
414 return false;
415 }
416
ReadUE(int * val)417 H264Parser::Result H264Parser::ReadUE(int* val) {
418 int num_bits = -1;
419 int bit;
420 int rest;
421
422 // Count the number of contiguous zero bits.
423 do {
424 READ_BITS_OR_RETURN(1, &bit);
425 num_bits++;
426 } while (bit == 0);
427
428 if (num_bits > 31)
429 return kInvalidStream;
430
431 // Calculate exp-Golomb code value of size num_bits.
432 // Special case for |num_bits| == 31 to avoid integer overflow. The only
433 // valid representation as an int is 2^31 - 1, so the remaining bits must
434 // be 0 or else the number is too large.
435 *val = (1u << num_bits) - 1u;
436
437 if (num_bits == 31) {
438 READ_BITS_OR_RETURN(num_bits, &rest);
439 return (rest == 0) ? kOk : kInvalidStream;
440 }
441
442 if (num_bits > 0) {
443 READ_BITS_OR_RETURN(num_bits, &rest);
444 *val += rest;
445 }
446
447 return kOk;
448 }
449
ReadSE(int * val)450 H264Parser::Result H264Parser::ReadSE(int* val) {
451 int ue;
452 Result res;
453
454 // See Chapter 9 in the spec.
455 res = ReadUE(&ue);
456 if (res != kOk)
457 return res;
458
459 if (ue % 2 == 0)
460 *val = -(ue / 2);
461 else
462 *val = ue / 2 + 1;
463
464 return kOk;
465 }
466
AdvanceToNextNALU(H264NALU * nalu)467 H264Parser::Result H264Parser::AdvanceToNextNALU(H264NALU* nalu) {
468 off_t start_code_size;
469 off_t nalu_size_with_start_code;
470 if (!LocateNALU(&nalu_size_with_start_code, &start_code_size)) {
471 DVLOG(4) << "Could not find next NALU, bytes left in stream: "
472 << bytes_left_;
473 stream_ = nullptr;
474 bytes_left_ = 0;
475 return kEOStream;
476 }
477
478 nalu->data = stream_ + start_code_size;
479 nalu->size = nalu_size_with_start_code - start_code_size;
480 DVLOG(4) << "NALU found: size=" << nalu_size_with_start_code;
481
482 // Initialize bit reader at the start of found NALU.
483 if (!br_.Initialize(nalu->data, nalu->size)) {
484 stream_ = nullptr;
485 bytes_left_ = 0;
486 return kEOStream;
487 }
488
489 // Move parser state to after this NALU, so next time AdvanceToNextNALU
490 // is called, we will effectively be skipping it;
491 // other parsing functions will use the position saved
492 // in bit reader for parsing, so we don't have to remember it here.
493 stream_ += nalu_size_with_start_code;
494 bytes_left_ -= nalu_size_with_start_code;
495
496 // Read NALU header, skip the forbidden_zero_bit, but check for it.
497 int data;
498 READ_BITS_OR_RETURN(1, &data);
499 TRUE_OR_RETURN(data == 0);
500
501 READ_BITS_OR_RETURN(2, &nalu->nal_ref_idc);
502 READ_BITS_OR_RETURN(5, &nalu->nal_unit_type);
503
504 DVLOG(4) << "NALU type: " << static_cast<int>(nalu->nal_unit_type)
505 << " at: " << reinterpret_cast<const void*>(nalu->data)
506 << " size: " << nalu->size
507 << " ref: " << static_cast<int>(nalu->nal_ref_idc);
508
509 return kOk;
510 }
511
512 // Default scaling lists (per spec).
513 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
514 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42,
515 };
516
517 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
518 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34,
519 };
520
521 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
522 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
523 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
524 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
525 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42,
526 };
527
528 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
529 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
530 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
531 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
532 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
533 };
534
DefaultScalingList4x4(int i,int scaling_list4x4[][kH264ScalingList4x4Length])535 static inline void DefaultScalingList4x4(
536 int i,
537 int scaling_list4x4[][kH264ScalingList4x4Length]) {
538 DCHECK_LT(i, 6);
539
540 if (i < 3)
541 memcpy(scaling_list4x4[i], kDefault4x4Intra, sizeof(kDefault4x4Intra));
542 else if (i < 6)
543 memcpy(scaling_list4x4[i], kDefault4x4Inter, sizeof(kDefault4x4Inter));
544 }
545
DefaultScalingList8x8(int i,int scaling_list8x8[][kH264ScalingList8x8Length])546 static inline void DefaultScalingList8x8(
547 int i,
548 int scaling_list8x8[][kH264ScalingList8x8Length]) {
549 DCHECK_LT(i, 6);
550
551 if (i % 2 == 0)
552 memcpy(scaling_list8x8[i], kDefault8x8Intra, sizeof(kDefault8x8Intra));
553 else
554 memcpy(scaling_list8x8[i], kDefault8x8Inter, sizeof(kDefault8x8Inter));
555 }
556
FallbackScalingList4x4(int i,const int default_scaling_list_intra[],const int default_scaling_list_inter[],int scaling_list4x4[][kH264ScalingList4x4Length])557 static void FallbackScalingList4x4(
558 int i,
559 const int default_scaling_list_intra[],
560 const int default_scaling_list_inter[],
561 int scaling_list4x4[][kH264ScalingList4x4Length]) {
562 static const int kScalingList4x4ByteSize =
563 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
564
565 switch (i) {
566 case 0:
567 memcpy(scaling_list4x4[i], default_scaling_list_intra,
568 kScalingList4x4ByteSize);
569 break;
570
571 case 1:
572 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
573 break;
574
575 case 2:
576 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
577 break;
578
579 case 3:
580 memcpy(scaling_list4x4[i], default_scaling_list_inter,
581 kScalingList4x4ByteSize);
582 break;
583
584 case 4:
585 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
586 break;
587
588 case 5:
589 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
590 break;
591
592 default:
593 NOTREACHED();
594 break;
595 }
596 }
597
FallbackScalingList8x8(int i,const int default_scaling_list_intra[],const int default_scaling_list_inter[],int scaling_list8x8[][kH264ScalingList8x8Length])598 static void FallbackScalingList8x8(
599 int i,
600 const int default_scaling_list_intra[],
601 const int default_scaling_list_inter[],
602 int scaling_list8x8[][kH264ScalingList8x8Length]) {
603 static const int kScalingList8x8ByteSize =
604 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
605
606 switch (i) {
607 case 0:
608 memcpy(scaling_list8x8[i], default_scaling_list_intra,
609 kScalingList8x8ByteSize);
610 break;
611
612 case 1:
613 memcpy(scaling_list8x8[i], default_scaling_list_inter,
614 kScalingList8x8ByteSize);
615 break;
616
617 case 2:
618 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
619 break;
620
621 case 3:
622 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
623 break;
624
625 case 4:
626 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
627 break;
628
629 case 5:
630 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
631 break;
632
633 default:
634 NOTREACHED();
635 break;
636 }
637 }
638
ParseScalingList(int size,int * scaling_list,bool * use_default)639 H264Parser::Result H264Parser::ParseScalingList(int size,
640 int* scaling_list,
641 bool* use_default) {
642 // See chapter 7.3.2.1.1.1.
643 int last_scale = 8;
644 int next_scale = 8;
645 int delta_scale;
646
647 *use_default = false;
648
649 for (int j = 0; j < size; ++j) {
650 if (next_scale != 0) {
651 READ_SE_OR_RETURN(&delta_scale);
652 IN_RANGE_OR_RETURN(delta_scale, -128, 127);
653 next_scale = (last_scale + delta_scale + 256) & 0xff;
654
655 if (j == 0 && next_scale == 0) {
656 *use_default = true;
657 return kOk;
658 }
659 }
660
661 scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
662 last_scale = scaling_list[j];
663 }
664
665 return kOk;
666 }
667
ParseSPSScalingLists(H264SPS * sps)668 H264Parser::Result H264Parser::ParseSPSScalingLists(H264SPS* sps) {
669 // See 7.4.2.1.1.
670 bool seq_scaling_list_present_flag;
671 bool use_default;
672 Result res;
673
674 // Parse scaling_list4x4.
675 for (int i = 0; i < 6; ++i) {
676 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
677
678 if (seq_scaling_list_present_flag) {
679 res = ParseScalingList(arraysize(sps->scaling_list4x4[i]),
680 sps->scaling_list4x4[i], &use_default);
681 if (res != kOk)
682 return res;
683
684 if (use_default)
685 DefaultScalingList4x4(i, sps->scaling_list4x4);
686
687 } else {
688 FallbackScalingList4x4(i, kDefault4x4Intra, kDefault4x4Inter,
689 sps->scaling_list4x4);
690 }
691 }
692
693 // Parse scaling_list8x8.
694 for (int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
695 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
696
697 if (seq_scaling_list_present_flag) {
698 res = ParseScalingList(arraysize(sps->scaling_list8x8[i]),
699 sps->scaling_list8x8[i], &use_default);
700 if (res != kOk)
701 return res;
702
703 if (use_default)
704 DefaultScalingList8x8(i, sps->scaling_list8x8);
705
706 } else {
707 FallbackScalingList8x8(i, kDefault8x8Intra, kDefault8x8Inter,
708 sps->scaling_list8x8);
709 }
710 }
711
712 return kOk;
713 }
714
ParsePPSScalingLists(const H264SPS & sps,H264PPS * pps)715 H264Parser::Result H264Parser::ParsePPSScalingLists(const H264SPS& sps,
716 H264PPS* pps) {
717 // See 7.4.2.2.
718 bool pic_scaling_list_present_flag;
719 bool use_default;
720 Result res;
721
722 for (int i = 0; i < 6; ++i) {
723 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
724
725 if (pic_scaling_list_present_flag) {
726 res = ParseScalingList(arraysize(pps->scaling_list4x4[i]),
727 pps->scaling_list4x4[i], &use_default);
728 if (res != kOk)
729 return res;
730
731 if (use_default)
732 DefaultScalingList4x4(i, pps->scaling_list4x4);
733
734 } else {
735 if (!sps.seq_scaling_matrix_present_flag) {
736 // Table 7-2 fallback rule A in spec.
737 FallbackScalingList4x4(i, kDefault4x4Intra, kDefault4x4Inter,
738 pps->scaling_list4x4);
739 } else {
740 // Table 7-2 fallback rule B in spec.
741 FallbackScalingList4x4(i, sps.scaling_list4x4[0],
742 sps.scaling_list4x4[3], pps->scaling_list4x4);
743 }
744 }
745 }
746
747 if (pps->transform_8x8_mode_flag) {
748 for (int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
749 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
750
751 if (pic_scaling_list_present_flag) {
752 res = ParseScalingList(arraysize(pps->scaling_list8x8[i]),
753 pps->scaling_list8x8[i], &use_default);
754 if (res != kOk)
755 return res;
756
757 if (use_default)
758 DefaultScalingList8x8(i, pps->scaling_list8x8);
759
760 } else {
761 if (!sps.seq_scaling_matrix_present_flag) {
762 // Table 7-2 fallback rule A in spec.
763 FallbackScalingList8x8(i, kDefault8x8Intra, kDefault8x8Inter,
764 pps->scaling_list8x8);
765 } else {
766 // Table 7-2 fallback rule B in spec.
767 FallbackScalingList8x8(i, sps.scaling_list8x8[0],
768 sps.scaling_list8x8[1], pps->scaling_list8x8);
769 }
770 }
771 }
772 }
773 return kOk;
774 }
775
ParseAndIgnoreHRDParameters(bool * hrd_parameters_present)776 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
777 bool* hrd_parameters_present) {
778 int data;
779 READ_BOOL_OR_RETURN(&data); // {nal,vcl}_hrd_parameters_present_flag
780 if (!data)
781 return kOk;
782
783 *hrd_parameters_present = true;
784
785 int cpb_cnt_minus1;
786 READ_UE_OR_RETURN(&cpb_cnt_minus1);
787 IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
788 READ_BITS_OR_RETURN(8, &data); // bit_rate_scale, cpb_size_scale
789 for (int i = 0; i <= cpb_cnt_minus1; ++i) {
790 READ_UE_OR_RETURN(&data); // bit_rate_value_minus1[i]
791 READ_UE_OR_RETURN(&data); // cpb_size_value_minus1[i]
792 READ_BOOL_OR_RETURN(&data); // cbr_flag
793 }
794 READ_BITS_OR_RETURN(20, &data); // cpb/dpb delays, etc.
795
796 return kOk;
797 }
798
ParseVUIParameters(H264SPS * sps)799 H264Parser::Result H264Parser::ParseVUIParameters(H264SPS* sps) {
800 bool aspect_ratio_info_present_flag;
801 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
802 if (aspect_ratio_info_present_flag) {
803 int aspect_ratio_idc;
804 READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
805 if (aspect_ratio_idc == H264SPS::kExtendedSar) {
806 READ_BITS_OR_RETURN(16, &sps->sar_width);
807 READ_BITS_OR_RETURN(16, &sps->sar_height);
808 } else {
809 const int max_aspect_ratio_idc = arraysize(kTableSarWidth) - 1;
810 IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
811 sps->sar_width = kTableSarWidth[aspect_ratio_idc];
812 sps->sar_height = kTableSarHeight[aspect_ratio_idc];
813 }
814 }
815
816 int data;
817 // Read and ignore overscan and video signal type info.
818 READ_BOOL_OR_RETURN(&data); // overscan_info_present_flag
819 if (data)
820 READ_BOOL_OR_RETURN(&data); // overscan_appropriate_flag
821
822 READ_BOOL_OR_RETURN(&sps->video_signal_type_present_flag);
823 if (sps->video_signal_type_present_flag) {
824 READ_BITS_OR_RETURN(3, &sps->video_format);
825 READ_BOOL_OR_RETURN(&sps->video_full_range_flag);
826 READ_BOOL_OR_RETURN(&sps->colour_description_present_flag);
827 if (sps->colour_description_present_flag) {
828 // color description syntax elements
829 READ_BITS_OR_RETURN(8, &sps->colour_primaries);
830 READ_BITS_OR_RETURN(8, &sps->transfer_characteristics);
831 READ_BITS_OR_RETURN(8, &sps->matrix_coefficients);
832 }
833 }
834
835 READ_BOOL_OR_RETURN(&data); // chroma_loc_info_present_flag
836 if (data) {
837 READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_top_field
838 READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_bottom_field
839 }
840
841 // Read and ignore timing info.
842 READ_BOOL_OR_RETURN(&data); // timing_info_present_flag
843 if (data) {
844 READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
845 READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
846 READ_BITS_OR_RETURN(16, &data); // time_scale
847 READ_BITS_OR_RETURN(16, &data); // time_scale
848 READ_BOOL_OR_RETURN(&data); // fixed_frame_rate_flag
849 }
850
851 // Read and ignore NAL HRD parameters, if present.
852 bool hrd_parameters_present = false;
853 Result res = ParseAndIgnoreHRDParameters(&hrd_parameters_present);
854 if (res != kOk)
855 return res;
856
857 // Read and ignore VCL HRD parameters, if present.
858 res = ParseAndIgnoreHRDParameters(&hrd_parameters_present);
859 if (res != kOk)
860 return res;
861
862 if (hrd_parameters_present) // One of NAL or VCL params present is enough.
863 READ_BOOL_OR_RETURN(&data); // low_delay_hrd_flag
864
865 READ_BOOL_OR_RETURN(&data); // pic_struct_present_flag
866 READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
867 if (sps->bitstream_restriction_flag) {
868 READ_BOOL_OR_RETURN(&data); // motion_vectors_over_pic_boundaries_flag
869 READ_UE_OR_RETURN(&data); // max_bytes_per_pic_denom
870 READ_UE_OR_RETURN(&data); // max_bits_per_mb_denom
871 READ_UE_OR_RETURN(&data); // log2_max_mv_length_horizontal
872 READ_UE_OR_RETURN(&data); // log2_max_mv_length_vertical
873 READ_UE_OR_RETURN(&sps->max_num_reorder_frames);
874 READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
875 TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
876 IN_RANGE_OR_RETURN(sps->max_num_reorder_frames, 0,
877 sps->max_dec_frame_buffering);
878 }
879
880 return kOk;
881 }
882
FillDefaultSeqScalingLists(H264SPS * sps)883 static void FillDefaultSeqScalingLists(H264SPS* sps) {
884 for (int i = 0; i < 6; ++i)
885 for (int j = 0; j < kH264ScalingList4x4Length; ++j)
886 sps->scaling_list4x4[i][j] = 16;
887
888 for (int i = 0; i < 6; ++i)
889 for (int j = 0; j < kH264ScalingList8x8Length; ++j)
890 sps->scaling_list8x8[i][j] = 16;
891 }
892
ParseSPS(int * sps_id)893 H264Parser::Result H264Parser::ParseSPS(int* sps_id) {
894 // See 7.4.2.1.
895 int data;
896 Result res;
897
898 *sps_id = -1;
899
900 std::unique_ptr<H264SPS> sps(new H264SPS());
901
902 READ_BITS_OR_RETURN(8, &sps->profile_idc);
903 READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
904 READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
905 READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
906 READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
907 READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
908 READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
909 READ_BITS_OR_RETURN(2, &data); // reserved_zero_2bits
910 READ_BITS_OR_RETURN(8, &sps->level_idc);
911 READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
912 TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
913
914 if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
915 sps->profile_idc == 122 || sps->profile_idc == 244 ||
916 sps->profile_idc == 44 || sps->profile_idc == 83 ||
917 sps->profile_idc == 86 || sps->profile_idc == 118 ||
918 sps->profile_idc == 128) {
919 READ_UE_OR_RETURN(&sps->chroma_format_idc);
920 TRUE_OR_RETURN(sps->chroma_format_idc < 4);
921
922 if (sps->chroma_format_idc == 3)
923 READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
924
925 READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
926 TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
927
928 READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
929 TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
930
931 READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
932 READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
933
934 if (sps->seq_scaling_matrix_present_flag) {
935 DVLOG(4) << "Scaling matrix present";
936 res = ParseSPSScalingLists(sps.get());
937 if (res != kOk)
938 return res;
939 } else {
940 FillDefaultSeqScalingLists(sps.get());
941 }
942 } else {
943 sps->chroma_format_idc = 1;
944 FillDefaultSeqScalingLists(sps.get());
945 }
946
947 if (sps->separate_colour_plane_flag)
948 sps->chroma_array_type = 0;
949 else
950 sps->chroma_array_type = sps->chroma_format_idc;
951
952 READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
953 TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
954
955 READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
956 TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
957
958 if (sps->pic_order_cnt_type == 0) {
959 READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
960 TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
961 sps->expected_delta_per_pic_order_cnt_cycle = 0;
962 } else if (sps->pic_order_cnt_type == 1) {
963 READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
964 READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
965 READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
966 READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
967 TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
968
969 base::CheckedNumeric<int> offset_acc = 0;
970 for (int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
971 READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
972 offset_acc += sps->offset_for_ref_frame[i];
973 }
974 if (!offset_acc.IsValid())
975 return kInvalidStream;
976 sps->expected_delta_per_pic_order_cnt_cycle = offset_acc.ValueOrDefault(0);
977 }
978
979 READ_UE_OR_RETURN(&sps->max_num_ref_frames);
980 READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
981
982 READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
983 READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
984
985 READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
986 if (!sps->frame_mbs_only_flag)
987 READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
988
989 READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
990
991 READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
992 if (sps->frame_cropping_flag) {
993 READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
994 READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
995 READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
996 READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
997 }
998
999 READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
1000 if (sps->vui_parameters_present_flag) {
1001 DVLOG(4) << "VUI parameters present";
1002 res = ParseVUIParameters(sps.get());
1003 if (res != kOk)
1004 return res;
1005 }
1006
1007 // If an SPS with the same id already exists, replace it.
1008 *sps_id = sps->seq_parameter_set_id;
1009 active_SPSes_[*sps_id] = std::move(sps);
1010
1011 return kOk;
1012 }
1013
ParsePPS(int * pps_id)1014 H264Parser::Result H264Parser::ParsePPS(int* pps_id) {
1015 // See 7.4.2.2.
1016 const H264SPS* sps;
1017 Result res;
1018
1019 *pps_id = -1;
1020
1021 std::unique_ptr<H264PPS> pps(new H264PPS());
1022
1023 READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
1024 READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
1025 TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
1026
1027 if (active_SPSes_.find(pps->seq_parameter_set_id) == active_SPSes_.end()) {
1028 DVLOG(1) << "Invalid stream, no SPS id: " << pps->seq_parameter_set_id;
1029 return kInvalidStream;
1030 }
1031
1032 sps = GetSPS(pps->seq_parameter_set_id);
1033 TRUE_OR_RETURN(sps);
1034
1035 READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
1036 READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
1037
1038 READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
1039 if (pps->num_slice_groups_minus1 > 1) {
1040 DVLOG(1) << "Slice groups not supported";
1041 return kUnsupportedStream;
1042 }
1043
1044 READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
1045 TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
1046
1047 READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
1048 TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
1049
1050 READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
1051 READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
1052 TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
1053
1054 READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
1055 IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
1056
1057 READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
1058 IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
1059
1060 READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
1061 IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
1062 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
1063
1064 READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
1065 READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
1066 READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
1067
1068 if (br_.HasMoreRBSPData()) {
1069 READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
1070 READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
1071
1072 if (pps->pic_scaling_matrix_present_flag) {
1073 DVLOG(4) << "Picture scaling matrix present";
1074 res = ParsePPSScalingLists(*sps, pps.get());
1075 if (res != kOk)
1076 return res;
1077 }
1078
1079 READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
1080 }
1081
1082 // If a PPS with the same id already exists, replace it.
1083 *pps_id = pps->pic_parameter_set_id;
1084 active_PPSes_[*pps_id] = std::move(pps);
1085
1086 return kOk;
1087 }
1088
ParseRefPicListModification(int num_ref_idx_active_minus1,H264ModificationOfPicNum * ref_list_mods)1089 H264Parser::Result H264Parser::ParseRefPicListModification(
1090 int num_ref_idx_active_minus1,
1091 H264ModificationOfPicNum* ref_list_mods) {
1092 H264ModificationOfPicNum* pic_num_mod;
1093
1094 if (num_ref_idx_active_minus1 >= 32)
1095 return kInvalidStream;
1096
1097 for (int i = 0; i < 32; ++i) {
1098 pic_num_mod = &ref_list_mods[i];
1099 READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
1100 TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
1101
1102 switch (pic_num_mod->modification_of_pic_nums_idc) {
1103 case 0:
1104 case 1:
1105 READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
1106 break;
1107
1108 case 2:
1109 READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
1110 break;
1111
1112 case 3:
1113 // Per spec, list cannot be empty.
1114 if (i == 0)
1115 return kInvalidStream;
1116 return kOk;
1117
1118 default:
1119 return kInvalidStream;
1120 }
1121 }
1122
1123 // If we got here, we didn't get loop end marker prematurely,
1124 // so make sure it is there for our client.
1125 int modification_of_pic_nums_idc;
1126 READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
1127 TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
1128
1129 return kOk;
1130 }
1131
ParseRefPicListModifications(H264SliceHeader * shdr)1132 H264Parser::Result H264Parser::ParseRefPicListModifications(
1133 H264SliceHeader* shdr) {
1134 Result res;
1135
1136 if (!shdr->IsISlice() && !shdr->IsSISlice()) {
1137 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
1138 if (shdr->ref_pic_list_modification_flag_l0) {
1139 res = ParseRefPicListModification(shdr->num_ref_idx_l0_active_minus1,
1140 shdr->ref_list_l0_modifications);
1141 if (res != kOk)
1142 return res;
1143 }
1144 }
1145
1146 if (shdr->IsBSlice()) {
1147 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
1148 if (shdr->ref_pic_list_modification_flag_l1) {
1149 res = ParseRefPicListModification(shdr->num_ref_idx_l1_active_minus1,
1150 shdr->ref_list_l1_modifications);
1151 if (res != kOk)
1152 return res;
1153 }
1154 }
1155
1156 return kOk;
1157 }
1158
ParseWeightingFactors(int num_ref_idx_active_minus1,int chroma_array_type,int luma_log2_weight_denom,int chroma_log2_weight_denom,H264WeightingFactors * w_facts)1159 H264Parser::Result H264Parser::ParseWeightingFactors(
1160 int num_ref_idx_active_minus1,
1161 int chroma_array_type,
1162 int luma_log2_weight_denom,
1163 int chroma_log2_weight_denom,
1164 H264WeightingFactors* w_facts) {
1165 int def_luma_weight = 1 << luma_log2_weight_denom;
1166 int def_chroma_weight = 1 << chroma_log2_weight_denom;
1167
1168 for (int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
1169 READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag);
1170 if (w_facts->luma_weight_flag) {
1171 READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
1172 IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
1173
1174 READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
1175 IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
1176 } else {
1177 w_facts->luma_weight[i] = def_luma_weight;
1178 w_facts->luma_offset[i] = 0;
1179 }
1180
1181 if (chroma_array_type != 0) {
1182 READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag);
1183 if (w_facts->chroma_weight_flag) {
1184 for (int j = 0; j < 2; ++j) {
1185 READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
1186 IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
1187
1188 READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
1189 IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
1190 }
1191 } else {
1192 for (int j = 0; j < 2; ++j) {
1193 w_facts->chroma_weight[i][j] = def_chroma_weight;
1194 w_facts->chroma_offset[i][j] = 0;
1195 }
1196 }
1197 }
1198 }
1199
1200 return kOk;
1201 }
1202
ParsePredWeightTable(const H264SPS & sps,H264SliceHeader * shdr)1203 H264Parser::Result H264Parser::ParsePredWeightTable(const H264SPS& sps,
1204 H264SliceHeader* shdr) {
1205 READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
1206 TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
1207
1208 if (sps.chroma_array_type != 0)
1209 READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
1210 TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
1211
1212 Result res = ParseWeightingFactors(
1213 shdr->num_ref_idx_l0_active_minus1, sps.chroma_array_type,
1214 shdr->luma_log2_weight_denom, shdr->chroma_log2_weight_denom,
1215 &shdr->pred_weight_table_l0);
1216 if (res != kOk)
1217 return res;
1218
1219 if (shdr->IsBSlice()) {
1220 res = ParseWeightingFactors(
1221 shdr->num_ref_idx_l1_active_minus1, sps.chroma_array_type,
1222 shdr->luma_log2_weight_denom, shdr->chroma_log2_weight_denom,
1223 &shdr->pred_weight_table_l1);
1224 if (res != kOk)
1225 return res;
1226 }
1227
1228 return kOk;
1229 }
1230
ParseDecRefPicMarking(H264SliceHeader * shdr)1231 H264Parser::Result H264Parser::ParseDecRefPicMarking(H264SliceHeader* shdr) {
1232 size_t bits_left_at_start = br_.NumBitsLeft();
1233
1234 if (shdr->idr_pic_flag) {
1235 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
1236 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
1237 } else {
1238 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
1239
1240 H264DecRefPicMarking* marking;
1241 if (shdr->adaptive_ref_pic_marking_mode_flag) {
1242 size_t i;
1243 for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) {
1244 marking = &shdr->ref_pic_marking[i];
1245
1246 READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
1247 if (marking->memory_mgmnt_control_operation == 0)
1248 break;
1249
1250 if (marking->memory_mgmnt_control_operation == 1 ||
1251 marking->memory_mgmnt_control_operation == 3)
1252 READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
1253
1254 if (marking->memory_mgmnt_control_operation == 2)
1255 READ_UE_OR_RETURN(&marking->long_term_pic_num);
1256
1257 if (marking->memory_mgmnt_control_operation == 3 ||
1258 marking->memory_mgmnt_control_operation == 6)
1259 READ_UE_OR_RETURN(&marking->long_term_frame_idx);
1260
1261 if (marking->memory_mgmnt_control_operation == 4)
1262 READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
1263
1264 if (marking->memory_mgmnt_control_operation > 6)
1265 return kInvalidStream;
1266 }
1267
1268 if (i == arraysize(shdr->ref_pic_marking)) {
1269 DVLOG(1) << "Ran out of dec ref pic marking fields";
1270 return kUnsupportedStream;
1271 }
1272 }
1273 }
1274
1275 shdr->dec_ref_pic_marking_bit_size = bits_left_at_start - br_.NumBitsLeft();
1276 return kOk;
1277 }
1278
ParseSliceHeader(const H264NALU & nalu,H264SliceHeader * shdr)1279 H264Parser::Result H264Parser::ParseSliceHeader(const H264NALU& nalu,
1280 H264SliceHeader* shdr) {
1281 // See 7.4.3.
1282 const H264SPS* sps;
1283 const H264PPS* pps;
1284 Result res;
1285
1286 memset(shdr, 0, sizeof(*shdr));
1287
1288 shdr->idr_pic_flag = (nalu.nal_unit_type == 5);
1289 shdr->nal_ref_idc = nalu.nal_ref_idc;
1290 shdr->nalu_data = nalu.data;
1291 shdr->nalu_size = nalu.size;
1292
1293 READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
1294 READ_UE_OR_RETURN(&shdr->slice_type);
1295 TRUE_OR_RETURN(shdr->slice_type < 10);
1296
1297 READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
1298
1299 pps = GetPPS(shdr->pic_parameter_set_id);
1300 TRUE_OR_RETURN(pps);
1301
1302 sps = GetSPS(pps->seq_parameter_set_id);
1303 TRUE_OR_RETURN(sps);
1304
1305 if (sps->separate_colour_plane_flag) {
1306 DVLOG(1) << "Interlaced streams not supported";
1307 return kUnsupportedStream;
1308 }
1309
1310 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1311 if (!sps->frame_mbs_only_flag) {
1312 READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1313 if (shdr->field_pic_flag) {
1314 DVLOG(1) << "Interlaced streams not supported";
1315 return kUnsupportedStream;
1316 }
1317 }
1318
1319 if (shdr->idr_pic_flag)
1320 READ_UE_OR_RETURN(&shdr->idr_pic_id);
1321
1322 size_t bits_left_at_pic_order_cnt_start = br_.NumBitsLeft();
1323 if (sps->pic_order_cnt_type == 0) {
1324 READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1325 &shdr->pic_order_cnt_lsb);
1326 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1327 !shdr->field_pic_flag)
1328 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1329 }
1330
1331 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1332 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt0);
1333 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1334 !shdr->field_pic_flag)
1335 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt1);
1336 }
1337
1338 shdr->pic_order_cnt_bit_size =
1339 bits_left_at_pic_order_cnt_start - br_.NumBitsLeft();
1340
1341 if (pps->redundant_pic_cnt_present_flag) {
1342 READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1343 TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1344 }
1345
1346 if (shdr->IsBSlice())
1347 READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1348
1349 if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1350 READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1351 if (shdr->num_ref_idx_active_override_flag) {
1352 READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1353 if (shdr->IsBSlice())
1354 READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1355 } else {
1356 shdr->num_ref_idx_l0_active_minus1 =
1357 pps->num_ref_idx_l0_default_active_minus1;
1358 if (shdr->IsBSlice()) {
1359 shdr->num_ref_idx_l1_active_minus1 =
1360 pps->num_ref_idx_l1_default_active_minus1;
1361 }
1362 }
1363 }
1364 if (shdr->field_pic_flag) {
1365 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1366 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1367 } else {
1368 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1369 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1370 }
1371
1372 if (nalu.nal_unit_type == H264NALU::kCodedSliceExtension) {
1373 return kUnsupportedStream;
1374 } else {
1375 res = ParseRefPicListModifications(shdr);
1376 if (res != kOk)
1377 return res;
1378 }
1379
1380 if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1381 (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1382 res = ParsePredWeightTable(*sps, shdr);
1383 if (res != kOk)
1384 return res;
1385 }
1386
1387 if (nalu.nal_ref_idc != 0) {
1388 res = ParseDecRefPicMarking(shdr);
1389 if (res != kOk)
1390 return res;
1391 }
1392
1393 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1394 !shdr->IsSISlice()) {
1395 READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1396 TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1397 }
1398
1399 READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1400
1401 if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1402 if (shdr->IsSPSlice())
1403 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1404 READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1405 }
1406
1407 if (pps->deblocking_filter_control_present_flag) {
1408 READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1409 TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1410
1411 if (shdr->disable_deblocking_filter_idc != 1) {
1412 READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1413 IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1414
1415 READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1416 IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1417 }
1418 }
1419
1420 if (pps->num_slice_groups_minus1 > 0) {
1421 DVLOG(1) << "Slice groups not supported";
1422 return kUnsupportedStream;
1423 }
1424
1425 size_t epb = br_.NumEmulationPreventionBytesRead();
1426 shdr->header_bit_size = (shdr->nalu_size - epb) * 8 - br_.NumBitsLeft();
1427
1428 return kOk;
1429 }
1430
ParseSEI(H264SEIMessage * sei_msg)1431 H264Parser::Result H264Parser::ParseSEI(H264SEIMessage* sei_msg) {
1432 int byte;
1433
1434 memset(sei_msg, 0, sizeof(*sei_msg));
1435
1436 READ_BITS_OR_RETURN(8, &byte);
1437 while (byte == 0xff) {
1438 sei_msg->type += 255;
1439 READ_BITS_OR_RETURN(8, &byte);
1440 }
1441 sei_msg->type += byte;
1442
1443 READ_BITS_OR_RETURN(8, &byte);
1444 while (byte == 0xff) {
1445 sei_msg->payload_size += 255;
1446 READ_BITS_OR_RETURN(8, &byte);
1447 }
1448 sei_msg->payload_size += byte;
1449
1450 DVLOG(4) << "Found SEI message type: " << sei_msg->type
1451 << " payload size: " << sei_msg->payload_size;
1452
1453 switch (sei_msg->type) {
1454 case H264SEIMessage::kSEIRecoveryPoint:
1455 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1456 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1457 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1458 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1459 break;
1460
1461 default:
1462 DVLOG(4) << "Unsupported SEI message";
1463 break;
1464 }
1465
1466 return kOk;
1467 }
1468
1469 } // namespace media
1470