Update V8 to version 4.7.42.
[chromium-blink-merge.git] / media / filters / h264_parser.cc
blobfe2a443e32845c77575fb101baa25a6101d56567
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.
5 #include "base/logging.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/stl_util.h"
9 #include "media/base/decrypt_config.h"
10 #include "media/filters/h264_parser.h"
12 namespace media {
14 bool H264SliceHeader::IsPSlice() const {
15 return (slice_type % 5 == kPSlice);
18 bool H264SliceHeader::IsBSlice() const {
19 return (slice_type % 5 == kBSlice);
22 bool H264SliceHeader::IsISlice() const {
23 return (slice_type % 5 == kISlice);
26 bool H264SliceHeader::IsSPSlice() const {
27 return (slice_type % 5 == kSPSlice);
30 bool H264SliceHeader::IsSISlice() const {
31 return (slice_type % 5 == kSISlice);
34 H264NALU::H264NALU() {
35 memset(this, 0, sizeof(*this));
38 H264SPS::H264SPS() {
39 memset(this, 0, sizeof(*this));
42 H264PPS::H264PPS() {
43 memset(this, 0, sizeof(*this));
46 H264SliceHeader::H264SliceHeader() {
47 memset(this, 0, sizeof(*this));
50 H264SEIMessage::H264SEIMessage() {
51 memset(this, 0, sizeof(*this));
54 #define READ_BITS_OR_RETURN(num_bits, out) \
55 do { \
56 int _out; \
57 if (!br_.ReadBits(num_bits, &_out)) { \
58 DVLOG(1) \
59 << "Error in stream: unexpected EOS while trying to read " #out; \
60 return kInvalidStream; \
61 } \
62 *out = _out; \
63 } while (0)
65 #define READ_BOOL_OR_RETURN(out) \
66 do { \
67 int _out; \
68 if (!br_.ReadBits(1, &_out)) { \
69 DVLOG(1) \
70 << "Error in stream: unexpected EOS while trying to read " #out; \
71 return kInvalidStream; \
72 } \
73 *out = _out != 0; \
74 } while (0)
76 #define READ_UE_OR_RETURN(out) \
77 do { \
78 if (ReadUE(out) != kOk) { \
79 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
80 return kInvalidStream; \
81 } \
82 } while (0)
84 #define READ_SE_OR_RETURN(out) \
85 do { \
86 if (ReadSE(out) != kOk) { \
87 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
88 return kInvalidStream; \
89 } \
90 } while (0)
92 #define IN_RANGE_OR_RETURN(val, min, max) \
93 do { \
94 if ((val) < (min) || (val) > (max)) { \
95 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
96 << " in range [" << (min) << ":" << (max) << "]" \
97 << " found " << (val) << " instead"; \
98 return kInvalidStream; \
99 } \
100 } while (0)
102 #define TRUE_OR_RETURN(a) \
103 do { \
104 if (!(a)) { \
105 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
106 return kInvalidStream; \
108 } while (0)
110 // ISO 14496 part 10
111 // VUI parameters: Table E-1 "Meaning of sample aspect ratio indicator"
112 static const int kTableSarWidth[] = {
113 0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
115 static const int kTableSarHeight[] = {
116 0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
118 static_assert(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
119 "sar tables must have the same size");
121 H264Parser::H264Parser() {
122 Reset();
125 H264Parser::~H264Parser() {
126 STLDeleteValues(&active_SPSes_);
127 STLDeleteValues(&active_PPSes_);
130 void H264Parser::Reset() {
131 stream_ = NULL;
132 bytes_left_ = 0;
133 encrypted_ranges_.clear();
136 void H264Parser::SetStream(const uint8* stream, off_t stream_size) {
137 std::vector<SubsampleEntry> subsamples;
138 SetEncryptedStream(stream, stream_size, subsamples);
141 void H264Parser::SetEncryptedStream(
142 const uint8* stream, off_t stream_size,
143 const std::vector<SubsampleEntry>& subsamples) {
144 DCHECK(stream);
145 DCHECK_GT(stream_size, 0);
147 stream_ = stream;
148 bytes_left_ = stream_size;
150 encrypted_ranges_.clear();
151 const uint8* start = stream;
152 const uint8* stream_end = stream_ + bytes_left_;
153 for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) {
154 start += subsamples[i].clear_bytes;
156 const uint8* end = std::min(start + subsamples[i].cypher_bytes, stream_end);
157 encrypted_ranges_.Add(start, end);
158 start = end;
162 const H264PPS* H264Parser::GetPPS(int pps_id) {
163 return active_PPSes_[pps_id];
166 const H264SPS* H264Parser::GetSPS(int sps_id) {
167 return active_SPSes_[sps_id];
170 static inline bool IsStartCode(const uint8* data) {
171 return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01;
174 // static
175 bool H264Parser::FindStartCode(const uint8* data, off_t data_size,
176 off_t* offset, off_t* start_code_size) {
177 DCHECK_GE(data_size, 0);
178 off_t bytes_left = data_size;
180 while (bytes_left >= 3) {
181 if (IsStartCode(data)) {
182 // Found three-byte start code, set pointer at its beginning.
183 *offset = data_size - bytes_left;
184 *start_code_size = 3;
186 // If there is a zero byte before this start code,
187 // then it's actually a four-byte start code, so backtrack one byte.
188 if (*offset > 0 && *(data - 1) == 0x00) {
189 --(*offset);
190 ++(*start_code_size);
193 return true;
196 ++data;
197 --bytes_left;
200 // End of data: offset is pointing to the first byte that was not considered
201 // as a possible start of a start code.
202 // Note: there is no security issue when receiving a negative |data_size|
203 // since in this case, |bytes_left| is equal to |data_size| and thus
204 // |*offset| is equal to 0 (valid offset).
205 *offset = data_size - bytes_left;
206 *start_code_size = 0;
207 return false;
210 bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) {
211 // Find the start code of next NALU.
212 off_t nalu_start_off = 0;
213 off_t annexb_start_code_size = 0;
215 if (!FindStartCodeInClearRanges(stream_, bytes_left_,
216 encrypted_ranges_,
217 &nalu_start_off, &annexb_start_code_size)) {
218 DVLOG(4) << "Could not find start code, end of stream?";
219 return false;
222 // Move the stream to the beginning of the NALU (pointing at the start code).
223 stream_ += nalu_start_off;
224 bytes_left_ -= nalu_start_off;
226 const uint8* nalu_data = stream_ + annexb_start_code_size;
227 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size;
228 if (max_nalu_data_size <= 0) {
229 DVLOG(3) << "End of stream";
230 return false;
233 // Find the start code of next NALU;
234 // if successful, |nalu_size_without_start_code| is the number of bytes from
235 // after previous start code to before this one;
236 // if next start code is not found, it is still a valid NALU since there
237 // are some bytes left after the first start code: all the remaining bytes
238 // belong to the current NALU.
239 off_t next_start_code_size = 0;
240 off_t nalu_size_without_start_code = 0;
241 if (!FindStartCodeInClearRanges(nalu_data, max_nalu_data_size,
242 encrypted_ranges_,
243 &nalu_size_without_start_code,
244 &next_start_code_size)) {
245 nalu_size_without_start_code = max_nalu_data_size;
247 *nalu_size = nalu_size_without_start_code + annexb_start_code_size;
248 *start_code_size = annexb_start_code_size;
249 return true;
252 bool H264Parser::FindStartCodeInClearRanges(
253 const uint8* data,
254 off_t data_size,
255 const Ranges<const uint8*>& encrypted_ranges,
256 off_t* offset,
257 off_t* start_code_size) {
258 if (encrypted_ranges.size() == 0)
259 return FindStartCode(data, data_size, offset, start_code_size);
261 DCHECK_GE(data_size, 0);
262 const uint8* start = data;
263 do {
264 off_t bytes_left = data_size - (start - data);
266 if (!FindStartCode(start, bytes_left, offset, start_code_size))
267 return false;
269 // Construct a Ranges object that represents the region occupied
270 // by the start code and the 1 byte needed to read the NAL unit type.
271 const uint8* start_code = start + *offset;
272 const uint8* start_code_end = start_code + *start_code_size;
273 Ranges<const uint8*> start_code_range;
274 start_code_range.Add(start_code, start_code_end + 1);
276 if (encrypted_ranges.IntersectionWith(start_code_range).size() > 0) {
277 // The start code is inside an encrypted section so we need to scan
278 // for another start code.
279 *start_code_size = 0;
280 start += std::min(*offset + 1, bytes_left);
282 } while (*start_code_size == 0);
284 // Update |*offset| to include the data we skipped over.
285 *offset += start - data;
286 return true;
289 H264Parser::Result H264Parser::ReadUE(int* val) {
290 int num_bits = -1;
291 int bit;
292 int rest;
294 // Count the number of contiguous zero bits.
295 do {
296 READ_BITS_OR_RETURN(1, &bit);
297 num_bits++;
298 } while (bit == 0);
300 if (num_bits > 31)
301 return kInvalidStream;
303 // Calculate exp-Golomb code value of size num_bits.
304 *val = (1 << num_bits) - 1;
306 if (num_bits > 0) {
307 READ_BITS_OR_RETURN(num_bits, &rest);
308 *val += rest;
311 return kOk;
314 H264Parser::Result H264Parser::ReadSE(int* val) {
315 int ue;
316 Result res;
318 // See Chapter 9 in the spec.
319 res = ReadUE(&ue);
320 if (res != kOk)
321 return res;
323 if (ue % 2 == 0)
324 *val = -(ue / 2);
325 else
326 *val = ue / 2 + 1;
328 return kOk;
331 H264Parser::Result H264Parser::AdvanceToNextNALU(H264NALU* nalu) {
332 off_t start_code_size;
333 off_t nalu_size_with_start_code;
334 if (!LocateNALU(&nalu_size_with_start_code, &start_code_size)) {
335 DVLOG(4) << "Could not find next NALU, bytes left in stream: "
336 << bytes_left_;
337 return kEOStream;
340 nalu->data = stream_ + start_code_size;
341 nalu->size = nalu_size_with_start_code - start_code_size;
342 DVLOG(4) << "NALU found: size=" << nalu_size_with_start_code;
344 // Initialize bit reader at the start of found NALU.
345 if (!br_.Initialize(nalu->data, nalu->size))
346 return kEOStream;
348 // Move parser state to after this NALU, so next time AdvanceToNextNALU
349 // is called, we will effectively be skipping it;
350 // other parsing functions will use the position saved
351 // in bit reader for parsing, so we don't have to remember it here.
352 stream_ += nalu_size_with_start_code;
353 bytes_left_ -= nalu_size_with_start_code;
355 // Read NALU header, skip the forbidden_zero_bit, but check for it.
356 int data;
357 READ_BITS_OR_RETURN(1, &data);
358 TRUE_OR_RETURN(data == 0);
360 READ_BITS_OR_RETURN(2, &nalu->nal_ref_idc);
361 READ_BITS_OR_RETURN(5, &nalu->nal_unit_type);
363 DVLOG(4) << "NALU type: " << static_cast<int>(nalu->nal_unit_type)
364 << " at: " << reinterpret_cast<const void*>(nalu->data)
365 << " size: " << nalu->size
366 << " ref: " << static_cast<int>(nalu->nal_ref_idc);
368 return kOk;
371 // Default scaling lists (per spec).
372 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
373 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
375 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
376 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
378 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
379 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
380 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
381 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
382 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
384 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
385 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
386 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
387 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
388 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
390 static inline void DefaultScalingList4x4(
391 int i,
392 int scaling_list4x4[][kH264ScalingList4x4Length]) {
393 DCHECK_LT(i, 6);
395 if (i < 3)
396 memcpy(scaling_list4x4[i], kDefault4x4Intra, sizeof(kDefault4x4Intra));
397 else if (i < 6)
398 memcpy(scaling_list4x4[i], kDefault4x4Inter, sizeof(kDefault4x4Inter));
401 static inline void DefaultScalingList8x8(
402 int i,
403 int scaling_list8x8[][kH264ScalingList8x8Length]) {
404 DCHECK_LT(i, 6);
406 if (i % 2 == 0)
407 memcpy(scaling_list8x8[i], kDefault8x8Intra, sizeof(kDefault8x8Intra));
408 else
409 memcpy(scaling_list8x8[i], kDefault8x8Inter, sizeof(kDefault8x8Inter));
412 static void FallbackScalingList4x4(
413 int i,
414 const int default_scaling_list_intra[],
415 const int default_scaling_list_inter[],
416 int scaling_list4x4[][kH264ScalingList4x4Length]) {
417 static const int kScalingList4x4ByteSize =
418 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
420 switch (i) {
421 case 0:
422 memcpy(scaling_list4x4[i], default_scaling_list_intra,
423 kScalingList4x4ByteSize);
424 break;
426 case 1:
427 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
428 break;
430 case 2:
431 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
432 break;
434 case 3:
435 memcpy(scaling_list4x4[i], default_scaling_list_inter,
436 kScalingList4x4ByteSize);
437 break;
439 case 4:
440 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
441 break;
443 case 5:
444 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
445 break;
447 default:
448 NOTREACHED();
449 break;
453 static void FallbackScalingList8x8(
454 int i,
455 const int default_scaling_list_intra[],
456 const int default_scaling_list_inter[],
457 int scaling_list8x8[][kH264ScalingList8x8Length]) {
458 static const int kScalingList8x8ByteSize =
459 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
461 switch (i) {
462 case 0:
463 memcpy(scaling_list8x8[i], default_scaling_list_intra,
464 kScalingList8x8ByteSize);
465 break;
467 case 1:
468 memcpy(scaling_list8x8[i], default_scaling_list_inter,
469 kScalingList8x8ByteSize);
470 break;
472 case 2:
473 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
474 break;
476 case 3:
477 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
478 break;
480 case 4:
481 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
482 break;
484 case 5:
485 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
486 break;
488 default:
489 NOTREACHED();
490 break;
494 H264Parser::Result H264Parser::ParseScalingList(int size,
495 int* scaling_list,
496 bool* use_default) {
497 // See chapter 7.3.2.1.1.1.
498 int last_scale = 8;
499 int next_scale = 8;
500 int delta_scale;
502 *use_default = false;
504 for (int j = 0; j < size; ++j) {
505 if (next_scale != 0) {
506 READ_SE_OR_RETURN(&delta_scale);
507 IN_RANGE_OR_RETURN(delta_scale, -128, 127);
508 next_scale = (last_scale + delta_scale + 256) & 0xff;
510 if (j == 0 && next_scale == 0) {
511 *use_default = true;
512 return kOk;
516 scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
517 last_scale = scaling_list[j];
520 return kOk;
523 H264Parser::Result H264Parser::ParseSPSScalingLists(H264SPS* sps) {
524 // See 7.4.2.1.1.
525 bool seq_scaling_list_present_flag;
526 bool use_default;
527 Result res;
529 // Parse scaling_list4x4.
530 for (int i = 0; i < 6; ++i) {
531 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
533 if (seq_scaling_list_present_flag) {
534 res = ParseScalingList(arraysize(sps->scaling_list4x4[i]),
535 sps->scaling_list4x4[i],
536 &use_default);
537 if (res != kOk)
538 return res;
540 if (use_default)
541 DefaultScalingList4x4(i, sps->scaling_list4x4);
543 } else {
544 FallbackScalingList4x4(
545 i, kDefault4x4Intra, kDefault4x4Inter, sps->scaling_list4x4);
549 // Parse scaling_list8x8.
550 for (int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
551 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
553 if (seq_scaling_list_present_flag) {
554 res = ParseScalingList(arraysize(sps->scaling_list8x8[i]),
555 sps->scaling_list8x8[i],
556 &use_default);
557 if (res != kOk)
558 return res;
560 if (use_default)
561 DefaultScalingList8x8(i, sps->scaling_list8x8);
563 } else {
564 FallbackScalingList8x8(
565 i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8);
569 return kOk;
572 H264Parser::Result H264Parser::ParsePPSScalingLists(const H264SPS& sps,
573 H264PPS* pps) {
574 // See 7.4.2.2.
575 bool pic_scaling_list_present_flag;
576 bool use_default;
577 Result res;
579 for (int i = 0; i < 6; ++i) {
580 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
582 if (pic_scaling_list_present_flag) {
583 res = ParseScalingList(arraysize(pps->scaling_list4x4[i]),
584 pps->scaling_list4x4[i],
585 &use_default);
586 if (res != kOk)
587 return res;
589 if (use_default)
590 DefaultScalingList4x4(i, pps->scaling_list4x4);
592 } else {
593 if (sps.seq_scaling_matrix_present_flag) {
594 // Table 7-2 fallback rule A in spec.
595 FallbackScalingList4x4(
596 i, kDefault4x4Intra, kDefault4x4Inter, pps->scaling_list4x4);
597 } else {
598 // Table 7-2 fallback rule B in spec.
599 FallbackScalingList4x4(i,
600 sps.scaling_list4x4[0],
601 sps.scaling_list4x4[3],
602 pps->scaling_list4x4);
607 if (pps->transform_8x8_mode_flag) {
608 for (int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
609 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
611 if (pic_scaling_list_present_flag) {
612 res = ParseScalingList(arraysize(pps->scaling_list8x8[i]),
613 pps->scaling_list8x8[i],
614 &use_default);
615 if (res != kOk)
616 return res;
618 if (use_default)
619 DefaultScalingList8x8(i, pps->scaling_list8x8);
621 } else {
622 if (sps.seq_scaling_matrix_present_flag) {
623 // Table 7-2 fallback rule A in spec.
624 FallbackScalingList8x8(
625 i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8);
626 } else {
627 // Table 7-2 fallback rule B in spec.
628 FallbackScalingList8x8(i,
629 sps.scaling_list8x8[0],
630 sps.scaling_list8x8[1],
631 pps->scaling_list8x8);
636 return kOk;
639 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
640 bool* hrd_parameters_present) {
641 int data;
642 READ_BOOL_OR_RETURN(&data); // {nal,vcl}_hrd_parameters_present_flag
643 if (!data)
644 return kOk;
646 *hrd_parameters_present = true;
648 int cpb_cnt_minus1;
649 READ_UE_OR_RETURN(&cpb_cnt_minus1);
650 IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
651 READ_BITS_OR_RETURN(8, &data); // bit_rate_scale, cpb_size_scale
652 for (int i = 0; i <= cpb_cnt_minus1; ++i) {
653 READ_UE_OR_RETURN(&data); // bit_rate_value_minus1[i]
654 READ_UE_OR_RETURN(&data); // cpb_size_value_minus1[i]
655 READ_BOOL_OR_RETURN(&data); // cbr_flag
657 READ_BITS_OR_RETURN(20, &data); // cpb/dpb delays, etc.
659 return kOk;
662 H264Parser::Result H264Parser::ParseVUIParameters(H264SPS* sps) {
663 bool aspect_ratio_info_present_flag;
664 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
665 if (aspect_ratio_info_present_flag) {
666 int aspect_ratio_idc;
667 READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
668 if (aspect_ratio_idc == H264SPS::kExtendedSar) {
669 READ_BITS_OR_RETURN(16, &sps->sar_width);
670 READ_BITS_OR_RETURN(16, &sps->sar_height);
671 } else {
672 const int max_aspect_ratio_idc = arraysize(kTableSarWidth) - 1;
673 IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
674 sps->sar_width = kTableSarWidth[aspect_ratio_idc];
675 sps->sar_height = kTableSarHeight[aspect_ratio_idc];
679 int data;
680 // Read and ignore overscan and video signal type info.
681 READ_BOOL_OR_RETURN(&data); // overscan_info_present_flag
682 if (data)
683 READ_BOOL_OR_RETURN(&data); // overscan_appropriate_flag
685 READ_BOOL_OR_RETURN(&data); // video_signal_type_present_flag
686 if (data) {
687 READ_BITS_OR_RETURN(3, &data); // video_format
688 READ_BOOL_OR_RETURN(&data); // video_full_range_flag
689 READ_BOOL_OR_RETURN(&data); // colour_description_present_flag
690 if (data)
691 READ_BITS_OR_RETURN(24, &data); // color description syntax elements
694 READ_BOOL_OR_RETURN(&data); // chroma_loc_info_present_flag
695 if (data) {
696 READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_top_field
697 READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_bottom_field
700 // Read and ignore timing info.
701 READ_BOOL_OR_RETURN(&data); // timing_info_present_flag
702 if (data) {
703 READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
704 READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
705 READ_BITS_OR_RETURN(16, &data); // time_scale
706 READ_BITS_OR_RETURN(16, &data); // time_scale
707 READ_BOOL_OR_RETURN(&data); // fixed_frame_rate_flag
710 // Read and ignore NAL HRD parameters, if present.
711 bool hrd_parameters_present = false;
712 Result res = ParseAndIgnoreHRDParameters(&hrd_parameters_present);
713 if (res != kOk)
714 return res;
716 // Read and ignore VCL HRD parameters, if present.
717 res = ParseAndIgnoreHRDParameters(&hrd_parameters_present);
718 if (res != kOk)
719 return res;
721 if (hrd_parameters_present) // One of NAL or VCL params present is enough.
722 READ_BOOL_OR_RETURN(&data); // low_delay_hrd_flag
724 READ_BOOL_OR_RETURN(&data); // pic_struct_present_flag
725 READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
726 if (sps->bitstream_restriction_flag) {
727 READ_BOOL_OR_RETURN(&data); // motion_vectors_over_pic_boundaries_flag
728 READ_UE_OR_RETURN(&data); // max_bytes_per_pic_denom
729 READ_UE_OR_RETURN(&data); // max_bits_per_mb_denom
730 READ_UE_OR_RETURN(&data); // log2_max_mv_length_horizontal
731 READ_UE_OR_RETURN(&data); // log2_max_mv_length_vertical
732 READ_UE_OR_RETURN(&sps->max_num_reorder_frames);
733 READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
734 TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
735 IN_RANGE_OR_RETURN(
736 sps->max_num_reorder_frames, 0, sps->max_dec_frame_buffering);
739 return kOk;
742 static void FillDefaultSeqScalingLists(H264SPS* sps) {
743 for (int i = 0; i < 6; ++i)
744 for (int j = 0; j < kH264ScalingList4x4Length; ++j)
745 sps->scaling_list4x4[i][j] = 16;
747 for (int i = 0; i < 6; ++i)
748 for (int j = 0; j < kH264ScalingList8x8Length; ++j)
749 sps->scaling_list8x8[i][j] = 16;
752 H264Parser::Result H264Parser::ParseSPS(int* sps_id) {
753 // See 7.4.2.1.
754 int data;
755 Result res;
757 *sps_id = -1;
759 scoped_ptr<H264SPS> sps(new H264SPS());
761 READ_BITS_OR_RETURN(8, &sps->profile_idc);
762 READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
763 READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
764 READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
765 READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
766 READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
767 READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
768 READ_BITS_OR_RETURN(2, &data); // reserved_zero_2bits
769 READ_BITS_OR_RETURN(8, &sps->level_idc);
770 READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
771 TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
773 if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
774 sps->profile_idc == 122 || sps->profile_idc == 244 ||
775 sps->profile_idc == 44 || sps->profile_idc == 83 ||
776 sps->profile_idc == 86 || sps->profile_idc == 118 ||
777 sps->profile_idc == 128) {
778 READ_UE_OR_RETURN(&sps->chroma_format_idc);
779 TRUE_OR_RETURN(sps->chroma_format_idc < 4);
781 if (sps->chroma_format_idc == 3)
782 READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
784 READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
785 TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
787 READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
788 TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
790 READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
791 READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
793 if (sps->seq_scaling_matrix_present_flag) {
794 DVLOG(4) << "Scaling matrix present";
795 res = ParseSPSScalingLists(sps.get());
796 if (res != kOk)
797 return res;
798 } else {
799 FillDefaultSeqScalingLists(sps.get());
801 } else {
802 sps->chroma_format_idc = 1;
803 FillDefaultSeqScalingLists(sps.get());
806 if (sps->separate_colour_plane_flag)
807 sps->chroma_array_type = 0;
808 else
809 sps->chroma_array_type = sps->chroma_format_idc;
811 READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
812 TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
814 READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
815 TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
817 sps->expected_delta_per_pic_order_cnt_cycle = 0;
818 if (sps->pic_order_cnt_type == 0) {
819 READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
820 TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
821 } else if (sps->pic_order_cnt_type == 1) {
822 READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
823 READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
824 READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
825 READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
826 TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
828 for (int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
829 READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
830 sps->expected_delta_per_pic_order_cnt_cycle +=
831 sps->offset_for_ref_frame[i];
835 READ_UE_OR_RETURN(&sps->max_num_ref_frames);
836 READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
838 if (sps->gaps_in_frame_num_value_allowed_flag)
839 return kUnsupportedStream;
841 READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
842 READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
844 READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
845 if (!sps->frame_mbs_only_flag)
846 READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
848 READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
850 READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
851 if (sps->frame_cropping_flag) {
852 READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
853 READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
854 READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
855 READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
858 READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
859 if (sps->vui_parameters_present_flag) {
860 DVLOG(4) << "VUI parameters present";
861 res = ParseVUIParameters(sps.get());
862 if (res != kOk)
863 return res;
866 // If an SPS with the same id already exists, replace it.
867 *sps_id = sps->seq_parameter_set_id;
868 delete active_SPSes_[*sps_id];
869 active_SPSes_[*sps_id] = sps.release();
871 return kOk;
874 H264Parser::Result H264Parser::ParsePPS(int* pps_id) {
875 // See 7.4.2.2.
876 const H264SPS* sps;
877 Result res;
879 *pps_id = -1;
881 scoped_ptr<H264PPS> pps(new H264PPS());
883 READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
884 READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
885 TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
887 sps = GetSPS(pps->seq_parameter_set_id);
888 TRUE_OR_RETURN(sps);
890 READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
891 READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
893 READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
894 if (pps->num_slice_groups_minus1 > 1) {
895 DVLOG(1) << "Slice groups not supported";
896 return kUnsupportedStream;
899 READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
900 TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
902 READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
903 TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
905 READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
906 READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
907 TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
909 READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
910 IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
912 READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
913 IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
915 READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
916 IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
917 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
919 READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
920 READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
921 READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
923 if (br_.HasMoreRBSPData()) {
924 READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
925 READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
927 if (pps->pic_scaling_matrix_present_flag) {
928 DVLOG(4) << "Picture scaling matrix present";
929 res = ParsePPSScalingLists(*sps, pps.get());
930 if (res != kOk)
931 return res;
934 READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
937 // If a PPS with the same id already exists, replace it.
938 *pps_id = pps->pic_parameter_set_id;
939 delete active_PPSes_[*pps_id];
940 active_PPSes_[*pps_id] = pps.release();
942 return kOk;
945 H264Parser::Result H264Parser::ParseRefPicListModification(
946 int num_ref_idx_active_minus1,
947 H264ModificationOfPicNum* ref_list_mods) {
948 H264ModificationOfPicNum* pic_num_mod;
950 if (num_ref_idx_active_minus1 >= 32)
951 return kInvalidStream;
953 for (int i = 0; i < 32; ++i) {
954 pic_num_mod = &ref_list_mods[i];
955 READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
956 TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
958 switch (pic_num_mod->modification_of_pic_nums_idc) {
959 case 0:
960 case 1:
961 READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
962 break;
964 case 2:
965 READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
966 break;
968 case 3:
969 // Per spec, list cannot be empty.
970 if (i == 0)
971 return kInvalidStream;
972 return kOk;
974 default:
975 return kInvalidStream;
979 // If we got here, we didn't get loop end marker prematurely,
980 // so make sure it is there for our client.
981 int modification_of_pic_nums_idc;
982 READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
983 TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
985 return kOk;
988 H264Parser::Result H264Parser::ParseRefPicListModifications(
989 H264SliceHeader* shdr) {
990 Result res;
992 if (!shdr->IsISlice() && !shdr->IsSISlice()) {
993 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
994 if (shdr->ref_pic_list_modification_flag_l0) {
995 res = ParseRefPicListModification(shdr->num_ref_idx_l0_active_minus1,
996 shdr->ref_list_l0_modifications);
997 if (res != kOk)
998 return res;
1002 if (shdr->IsBSlice()) {
1003 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
1004 if (shdr->ref_pic_list_modification_flag_l1) {
1005 res = ParseRefPicListModification(shdr->num_ref_idx_l1_active_minus1,
1006 shdr->ref_list_l1_modifications);
1007 if (res != kOk)
1008 return res;
1012 return kOk;
1015 H264Parser::Result H264Parser::ParseWeightingFactors(
1016 int num_ref_idx_active_minus1,
1017 int chroma_array_type,
1018 int luma_log2_weight_denom,
1019 int chroma_log2_weight_denom,
1020 H264WeightingFactors* w_facts) {
1022 int def_luma_weight = 1 << luma_log2_weight_denom;
1023 int def_chroma_weight = 1 << chroma_log2_weight_denom;
1025 for (int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
1026 READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag);
1027 if (w_facts->luma_weight_flag) {
1028 READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
1029 IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
1031 READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
1032 IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
1033 } else {
1034 w_facts->luma_weight[i] = def_luma_weight;
1035 w_facts->luma_offset[i] = 0;
1038 if (chroma_array_type != 0) {
1039 READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag);
1040 if (w_facts->chroma_weight_flag) {
1041 for (int j = 0; j < 2; ++j) {
1042 READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
1043 IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
1045 READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
1046 IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
1048 } else {
1049 for (int j = 0; j < 2; ++j) {
1050 w_facts->chroma_weight[i][j] = def_chroma_weight;
1051 w_facts->chroma_offset[i][j] = 0;
1057 return kOk;
1060 H264Parser::Result H264Parser::ParsePredWeightTable(const H264SPS& sps,
1061 H264SliceHeader* shdr) {
1062 READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
1063 TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
1065 if (sps.chroma_array_type != 0)
1066 READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
1067 TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
1069 Result res = ParseWeightingFactors(shdr->num_ref_idx_l0_active_minus1,
1070 sps.chroma_array_type,
1071 shdr->luma_log2_weight_denom,
1072 shdr->chroma_log2_weight_denom,
1073 &shdr->pred_weight_table_l0);
1074 if (res != kOk)
1075 return res;
1077 if (shdr->IsBSlice()) {
1078 res = ParseWeightingFactors(shdr->num_ref_idx_l1_active_minus1,
1079 sps.chroma_array_type,
1080 shdr->luma_log2_weight_denom,
1081 shdr->chroma_log2_weight_denom,
1082 &shdr->pred_weight_table_l1);
1083 if (res != kOk)
1084 return res;
1087 return kOk;
1090 H264Parser::Result H264Parser::ParseDecRefPicMarking(H264SliceHeader* shdr) {
1091 size_t bits_left_at_start = br_.NumBitsLeft();
1093 if (shdr->idr_pic_flag) {
1094 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
1095 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
1096 } else {
1097 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
1099 H264DecRefPicMarking* marking;
1100 if (shdr->adaptive_ref_pic_marking_mode_flag) {
1101 size_t i;
1102 for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) {
1103 marking = &shdr->ref_pic_marking[i];
1105 READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
1106 if (marking->memory_mgmnt_control_operation == 0)
1107 break;
1109 if (marking->memory_mgmnt_control_operation == 1 ||
1110 marking->memory_mgmnt_control_operation == 3)
1111 READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
1113 if (marking->memory_mgmnt_control_operation == 2)
1114 READ_UE_OR_RETURN(&marking->long_term_pic_num);
1116 if (marking->memory_mgmnt_control_operation == 3 ||
1117 marking->memory_mgmnt_control_operation == 6)
1118 READ_UE_OR_RETURN(&marking->long_term_frame_idx);
1120 if (marking->memory_mgmnt_control_operation == 4)
1121 READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
1123 if (marking->memory_mgmnt_control_operation > 6)
1124 return kInvalidStream;
1127 if (i == arraysize(shdr->ref_pic_marking)) {
1128 DVLOG(1) << "Ran out of dec ref pic marking fields";
1129 return kUnsupportedStream;
1134 shdr->dec_ref_pic_marking_bit_size = bits_left_at_start - br_.NumBitsLeft();
1135 return kOk;
1138 H264Parser::Result H264Parser::ParseSliceHeader(const H264NALU& nalu,
1139 H264SliceHeader* shdr) {
1140 // See 7.4.3.
1141 const H264SPS* sps;
1142 const H264PPS* pps;
1143 Result res;
1145 memset(shdr, 0, sizeof(*shdr));
1147 shdr->idr_pic_flag = (nalu.nal_unit_type == 5);
1148 shdr->nal_ref_idc = nalu.nal_ref_idc;
1149 shdr->nalu_data = nalu.data;
1150 shdr->nalu_size = nalu.size;
1152 READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
1153 READ_UE_OR_RETURN(&shdr->slice_type);
1154 TRUE_OR_RETURN(shdr->slice_type < 10);
1156 READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
1158 pps = GetPPS(shdr->pic_parameter_set_id);
1159 TRUE_OR_RETURN(pps);
1161 sps = GetSPS(pps->seq_parameter_set_id);
1162 TRUE_OR_RETURN(sps);
1164 if (sps->separate_colour_plane_flag) {
1165 DVLOG(1) << "Interlaced streams not supported";
1166 return kUnsupportedStream;
1169 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1170 if (!sps->frame_mbs_only_flag) {
1171 READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1172 if (shdr->field_pic_flag) {
1173 DVLOG(1) << "Interlaced streams not supported";
1174 return kUnsupportedStream;
1178 if (shdr->idr_pic_flag)
1179 READ_UE_OR_RETURN(&shdr->idr_pic_id);
1181 size_t bits_left_at_pic_order_cnt_start = br_.NumBitsLeft();
1182 if (sps->pic_order_cnt_type == 0) {
1183 READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1184 &shdr->pic_order_cnt_lsb);
1185 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1186 !shdr->field_pic_flag)
1187 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1190 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1191 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt0);
1192 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1193 !shdr->field_pic_flag)
1194 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt1);
1197 shdr->pic_order_cnt_bit_size =
1198 bits_left_at_pic_order_cnt_start - br_.NumBitsLeft();
1200 if (pps->redundant_pic_cnt_present_flag) {
1201 READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1202 TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1205 if (shdr->IsBSlice())
1206 READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1208 if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1209 READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1210 if (shdr->num_ref_idx_active_override_flag) {
1211 READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1212 if (shdr->IsBSlice())
1213 READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1214 } else {
1215 shdr->num_ref_idx_l0_active_minus1 =
1216 pps->num_ref_idx_l0_default_active_minus1;
1217 if (shdr->IsBSlice()) {
1218 shdr->num_ref_idx_l1_active_minus1 =
1219 pps->num_ref_idx_l1_default_active_minus1;
1223 if (shdr->field_pic_flag) {
1224 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1225 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1226 } else {
1227 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1228 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1231 if (nalu.nal_unit_type == H264NALU::kCodedSliceExtension) {
1232 return kUnsupportedStream;
1233 } else {
1234 res = ParseRefPicListModifications(shdr);
1235 if (res != kOk)
1236 return res;
1239 if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1240 (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1241 res = ParsePredWeightTable(*sps, shdr);
1242 if (res != kOk)
1243 return res;
1246 if (nalu.nal_ref_idc != 0) {
1247 res = ParseDecRefPicMarking(shdr);
1248 if (res != kOk)
1249 return res;
1252 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1253 !shdr->IsSISlice()) {
1254 READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1255 TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1258 READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1260 if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1261 if (shdr->IsSPSlice())
1262 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1263 READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1266 if (pps->deblocking_filter_control_present_flag) {
1267 READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1268 TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1270 if (shdr->disable_deblocking_filter_idc != 1) {
1271 READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1272 IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1274 READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1275 IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1279 if (pps->num_slice_groups_minus1 > 0) {
1280 DVLOG(1) << "Slice groups not supported";
1281 return kUnsupportedStream;
1284 size_t epb = br_.NumEmulationPreventionBytesRead();
1285 shdr->header_bit_size = (shdr->nalu_size - epb) * 8 - br_.NumBitsLeft();
1287 return kOk;
1290 H264Parser::Result H264Parser::ParseSEI(H264SEIMessage* sei_msg) {
1291 int byte;
1293 memset(sei_msg, 0, sizeof(*sei_msg));
1295 READ_BITS_OR_RETURN(8, &byte);
1296 while (byte == 0xff) {
1297 sei_msg->type += 255;
1298 READ_BITS_OR_RETURN(8, &byte);
1300 sei_msg->type += byte;
1302 READ_BITS_OR_RETURN(8, &byte);
1303 while (byte == 0xff) {
1304 sei_msg->payload_size += 255;
1305 READ_BITS_OR_RETURN(8, &byte);
1307 sei_msg->payload_size += byte;
1309 DVLOG(4) << "Found SEI message type: " << sei_msg->type
1310 << " payload size: " << sei_msg->payload_size;
1312 switch (sei_msg->type) {
1313 case H264SEIMessage::kSEIRecoveryPoint:
1314 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1315 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1316 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1317 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1318 break;
1320 default:
1321 DVLOG(4) << "Unsupported SEI message";
1322 break;
1325 return kOk;
1328 } // namespace media