bluetooth: android: Initial Low Energy Discovery Sessions.
[chromium-blink-merge.git] / media / filters / h264_parser.cc
blob22d420bcc6902387f152dda6f2dc53ce5d16df65
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 &nalu_start_off, &annexb_start_code_size)) {
217 DVLOG(4) << "Could not find start code, end of stream?";
218 return false;
221 // Move the stream to the beginning of the NALU (pointing at the start code).
222 stream_ += nalu_start_off;
223 bytes_left_ -= nalu_start_off;
225 const uint8* nalu_data = stream_ + annexb_start_code_size;
226 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size;
227 if (max_nalu_data_size <= 0) {
228 DVLOG(3) << "End of stream";
229 return false;
232 // Find the start code of next NALU;
233 // if successful, |nalu_size_without_start_code| is the number of bytes from
234 // after previous start code to before this one;
235 // if next start code is not found, it is still a valid NALU since there
236 // are some bytes left after the first start code: all the remaining bytes
237 // belong to the current NALU.
238 off_t next_start_code_size = 0;
239 off_t nalu_size_without_start_code = 0;
240 if (!FindStartCodeInClearRanges(nalu_data, max_nalu_data_size,
241 &nalu_size_without_start_code,
242 &next_start_code_size)) {
243 nalu_size_without_start_code = max_nalu_data_size;
245 *nalu_size = nalu_size_without_start_code + annexb_start_code_size;
246 *start_code_size = annexb_start_code_size;
247 return true;
250 bool H264Parser::FindStartCodeInClearRanges(
251 const uint8* data,
252 off_t data_size,
253 off_t* offset,
254 off_t* start_code_size) {
255 if (encrypted_ranges_.size() == 0)
256 return FindStartCode(data, data_size, offset, start_code_size);
258 DCHECK_GE(data_size, 0);
259 const uint8* start = data;
260 do {
261 off_t bytes_left = data_size - (start - data);
263 if (!FindStartCode(start, bytes_left, offset, start_code_size))
264 return false;
266 // Construct a Ranges object that represents the region occupied
267 // by the start code and the 1 byte needed to read the NAL unit type.
268 const uint8* start_code = start + *offset;
269 const uint8* start_code_end = start_code + *start_code_size;
270 Ranges<const uint8*> start_code_range;
271 start_code_range.Add(start_code, start_code_end + 1);
273 if (encrypted_ranges_.IntersectionWith(start_code_range).size() > 0) {
274 // The start code is inside an encrypted section so we need to scan
275 // for another start code.
276 *start_code_size = 0;
277 start += std::min(*offset + 1, bytes_left);
279 } while (*start_code_size == 0);
281 // Update |*offset| to include the data we skipped over.
282 *offset += start - data;
283 return true;
286 H264Parser::Result H264Parser::ReadUE(int* val) {
287 int num_bits = -1;
288 int bit;
289 int rest;
291 // Count the number of contiguous zero bits.
292 do {
293 READ_BITS_OR_RETURN(1, &bit);
294 num_bits++;
295 } while (bit == 0);
297 if (num_bits > 31)
298 return kInvalidStream;
300 // Calculate exp-Golomb code value of size num_bits.
301 *val = (1 << num_bits) - 1;
303 if (num_bits > 0) {
304 READ_BITS_OR_RETURN(num_bits, &rest);
305 *val += rest;
308 return kOk;
311 H264Parser::Result H264Parser::ReadSE(int* val) {
312 int ue;
313 Result res;
315 // See Chapter 9 in the spec.
316 res = ReadUE(&ue);
317 if (res != kOk)
318 return res;
320 if (ue % 2 == 0)
321 *val = -(ue / 2);
322 else
323 *val = ue / 2 + 1;
325 return kOk;
328 H264Parser::Result H264Parser::AdvanceToNextNALU(H264NALU* nalu) {
329 off_t start_code_size;
330 off_t nalu_size_with_start_code;
331 if (!LocateNALU(&nalu_size_with_start_code, &start_code_size)) {
332 DVLOG(4) << "Could not find next NALU, bytes left in stream: "
333 << bytes_left_;
334 return kEOStream;
337 nalu->data = stream_ + start_code_size;
338 nalu->size = nalu_size_with_start_code - start_code_size;
339 DVLOG(4) << "NALU found: size=" << nalu_size_with_start_code;
341 // Initialize bit reader at the start of found NALU.
342 if (!br_.Initialize(nalu->data, nalu->size))
343 return kEOStream;
345 // Move parser state to after this NALU, so next time AdvanceToNextNALU
346 // is called, we will effectively be skipping it;
347 // other parsing functions will use the position saved
348 // in bit reader for parsing, so we don't have to remember it here.
349 stream_ += nalu_size_with_start_code;
350 bytes_left_ -= nalu_size_with_start_code;
352 // Read NALU header, skip the forbidden_zero_bit, but check for it.
353 int data;
354 READ_BITS_OR_RETURN(1, &data);
355 TRUE_OR_RETURN(data == 0);
357 READ_BITS_OR_RETURN(2, &nalu->nal_ref_idc);
358 READ_BITS_OR_RETURN(5, &nalu->nal_unit_type);
360 DVLOG(4) << "NALU type: " << static_cast<int>(nalu->nal_unit_type)
361 << " at: " << reinterpret_cast<const void*>(nalu->data)
362 << " size: " << nalu->size
363 << " ref: " << static_cast<int>(nalu->nal_ref_idc);
365 return kOk;
368 // Default scaling lists (per spec).
369 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
370 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
372 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
373 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
375 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
376 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
377 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
378 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
379 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
381 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
382 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
383 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
384 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
385 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
387 static inline void DefaultScalingList4x4(
388 int i,
389 int scaling_list4x4[][kH264ScalingList4x4Length]) {
390 DCHECK_LT(i, 6);
392 if (i < 3)
393 memcpy(scaling_list4x4[i], kDefault4x4Intra, sizeof(kDefault4x4Intra));
394 else if (i < 6)
395 memcpy(scaling_list4x4[i], kDefault4x4Inter, sizeof(kDefault4x4Inter));
398 static inline void DefaultScalingList8x8(
399 int i,
400 int scaling_list8x8[][kH264ScalingList8x8Length]) {
401 DCHECK_LT(i, 6);
403 if (i % 2 == 0)
404 memcpy(scaling_list8x8[i], kDefault8x8Intra, sizeof(kDefault8x8Intra));
405 else
406 memcpy(scaling_list8x8[i], kDefault8x8Inter, sizeof(kDefault8x8Inter));
409 static void FallbackScalingList4x4(
410 int i,
411 const int default_scaling_list_intra[],
412 const int default_scaling_list_inter[],
413 int scaling_list4x4[][kH264ScalingList4x4Length]) {
414 static const int kScalingList4x4ByteSize =
415 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
417 switch (i) {
418 case 0:
419 memcpy(scaling_list4x4[i], default_scaling_list_intra,
420 kScalingList4x4ByteSize);
421 break;
423 case 1:
424 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
425 break;
427 case 2:
428 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
429 break;
431 case 3:
432 memcpy(scaling_list4x4[i], default_scaling_list_inter,
433 kScalingList4x4ByteSize);
434 break;
436 case 4:
437 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
438 break;
440 case 5:
441 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
442 break;
444 default:
445 NOTREACHED();
446 break;
450 static void FallbackScalingList8x8(
451 int i,
452 const int default_scaling_list_intra[],
453 const int default_scaling_list_inter[],
454 int scaling_list8x8[][kH264ScalingList8x8Length]) {
455 static const int kScalingList8x8ByteSize =
456 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
458 switch (i) {
459 case 0:
460 memcpy(scaling_list8x8[i], default_scaling_list_intra,
461 kScalingList8x8ByteSize);
462 break;
464 case 1:
465 memcpy(scaling_list8x8[i], default_scaling_list_inter,
466 kScalingList8x8ByteSize);
467 break;
469 case 2:
470 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
471 break;
473 case 3:
474 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
475 break;
477 case 4:
478 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
479 break;
481 case 5:
482 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
483 break;
485 default:
486 NOTREACHED();
487 break;
491 H264Parser::Result H264Parser::ParseScalingList(int size,
492 int* scaling_list,
493 bool* use_default) {
494 // See chapter 7.3.2.1.1.1.
495 int last_scale = 8;
496 int next_scale = 8;
497 int delta_scale;
499 *use_default = false;
501 for (int j = 0; j < size; ++j) {
502 if (next_scale != 0) {
503 READ_SE_OR_RETURN(&delta_scale);
504 IN_RANGE_OR_RETURN(delta_scale, -128, 127);
505 next_scale = (last_scale + delta_scale + 256) & 0xff;
507 if (j == 0 && next_scale == 0) {
508 *use_default = true;
509 return kOk;
513 scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
514 last_scale = scaling_list[j];
517 return kOk;
520 H264Parser::Result H264Parser::ParseSPSScalingLists(H264SPS* sps) {
521 // See 7.4.2.1.1.
522 bool seq_scaling_list_present_flag;
523 bool use_default;
524 Result res;
526 // Parse scaling_list4x4.
527 for (int i = 0; i < 6; ++i) {
528 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
530 if (seq_scaling_list_present_flag) {
531 res = ParseScalingList(arraysize(sps->scaling_list4x4[i]),
532 sps->scaling_list4x4[i],
533 &use_default);
534 if (res != kOk)
535 return res;
537 if (use_default)
538 DefaultScalingList4x4(i, sps->scaling_list4x4);
540 } else {
541 FallbackScalingList4x4(
542 i, kDefault4x4Intra, kDefault4x4Inter, sps->scaling_list4x4);
546 // Parse scaling_list8x8.
547 for (int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
548 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
550 if (seq_scaling_list_present_flag) {
551 res = ParseScalingList(arraysize(sps->scaling_list8x8[i]),
552 sps->scaling_list8x8[i],
553 &use_default);
554 if (res != kOk)
555 return res;
557 if (use_default)
558 DefaultScalingList8x8(i, sps->scaling_list8x8);
560 } else {
561 FallbackScalingList8x8(
562 i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8);
566 return kOk;
569 H264Parser::Result H264Parser::ParsePPSScalingLists(const H264SPS& sps,
570 H264PPS* pps) {
571 // See 7.4.2.2.
572 bool pic_scaling_list_present_flag;
573 bool use_default;
574 Result res;
576 for (int i = 0; i < 6; ++i) {
577 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
579 if (pic_scaling_list_present_flag) {
580 res = ParseScalingList(arraysize(pps->scaling_list4x4[i]),
581 pps->scaling_list4x4[i],
582 &use_default);
583 if (res != kOk)
584 return res;
586 if (use_default)
587 DefaultScalingList4x4(i, pps->scaling_list4x4);
589 } else {
590 if (sps.seq_scaling_matrix_present_flag) {
591 // Table 7-2 fallback rule A in spec.
592 FallbackScalingList4x4(
593 i, kDefault4x4Intra, kDefault4x4Inter, pps->scaling_list4x4);
594 } else {
595 // Table 7-2 fallback rule B in spec.
596 FallbackScalingList4x4(i,
597 sps.scaling_list4x4[0],
598 sps.scaling_list4x4[3],
599 pps->scaling_list4x4);
604 if (pps->transform_8x8_mode_flag) {
605 for (int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
606 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
608 if (pic_scaling_list_present_flag) {
609 res = ParseScalingList(arraysize(pps->scaling_list8x8[i]),
610 pps->scaling_list8x8[i],
611 &use_default);
612 if (res != kOk)
613 return res;
615 if (use_default)
616 DefaultScalingList8x8(i, pps->scaling_list8x8);
618 } else {
619 if (sps.seq_scaling_matrix_present_flag) {
620 // Table 7-2 fallback rule A in spec.
621 FallbackScalingList8x8(
622 i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8);
623 } else {
624 // Table 7-2 fallback rule B in spec.
625 FallbackScalingList8x8(i,
626 sps.scaling_list8x8[0],
627 sps.scaling_list8x8[1],
628 pps->scaling_list8x8);
633 return kOk;
636 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
637 bool* hrd_parameters_present) {
638 int data;
639 READ_BOOL_OR_RETURN(&data); // {nal,vcl}_hrd_parameters_present_flag
640 if (!data)
641 return kOk;
643 *hrd_parameters_present = true;
645 int cpb_cnt_minus1;
646 READ_UE_OR_RETURN(&cpb_cnt_minus1);
647 IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
648 READ_BITS_OR_RETURN(8, &data); // bit_rate_scale, cpb_size_scale
649 for (int i = 0; i <= cpb_cnt_minus1; ++i) {
650 READ_UE_OR_RETURN(&data); // bit_rate_value_minus1[i]
651 READ_UE_OR_RETURN(&data); // cpb_size_value_minus1[i]
652 READ_BOOL_OR_RETURN(&data); // cbr_flag
654 READ_BITS_OR_RETURN(20, &data); // cpb/dpb delays, etc.
656 return kOk;
659 H264Parser::Result H264Parser::ParseVUIParameters(H264SPS* sps) {
660 bool aspect_ratio_info_present_flag;
661 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
662 if (aspect_ratio_info_present_flag) {
663 int aspect_ratio_idc;
664 READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
665 if (aspect_ratio_idc == H264SPS::kExtendedSar) {
666 READ_BITS_OR_RETURN(16, &sps->sar_width);
667 READ_BITS_OR_RETURN(16, &sps->sar_height);
668 } else {
669 const int max_aspect_ratio_idc = arraysize(kTableSarWidth) - 1;
670 IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
671 sps->sar_width = kTableSarWidth[aspect_ratio_idc];
672 sps->sar_height = kTableSarHeight[aspect_ratio_idc];
676 int data;
677 // Read and ignore overscan and video signal type info.
678 READ_BOOL_OR_RETURN(&data); // overscan_info_present_flag
679 if (data)
680 READ_BOOL_OR_RETURN(&data); // overscan_appropriate_flag
682 READ_BOOL_OR_RETURN(&data); // video_signal_type_present_flag
683 if (data) {
684 READ_BITS_OR_RETURN(3, &data); // video_format
685 READ_BOOL_OR_RETURN(&data); // video_full_range_flag
686 READ_BOOL_OR_RETURN(&data); // colour_description_present_flag
687 if (data)
688 READ_BITS_OR_RETURN(24, &data); // color description syntax elements
691 READ_BOOL_OR_RETURN(&data); // chroma_loc_info_present_flag
692 if (data) {
693 READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_top_field
694 READ_UE_OR_RETURN(&data); // chroma_sample_loc_type_bottom_field
697 // Read and ignore timing info.
698 READ_BOOL_OR_RETURN(&data); // timing_info_present_flag
699 if (data) {
700 READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
701 READ_BITS_OR_RETURN(16, &data); // num_units_in_tick
702 READ_BITS_OR_RETURN(16, &data); // time_scale
703 READ_BITS_OR_RETURN(16, &data); // time_scale
704 READ_BOOL_OR_RETURN(&data); // fixed_frame_rate_flag
707 // Read and ignore NAL HRD parameters, if present.
708 bool hrd_parameters_present = false;
709 Result res = ParseAndIgnoreHRDParameters(&hrd_parameters_present);
710 if (res != kOk)
711 return res;
713 // Read and ignore VCL HRD parameters, if present.
714 res = ParseAndIgnoreHRDParameters(&hrd_parameters_present);
715 if (res != kOk)
716 return res;
718 if (hrd_parameters_present) // One of NAL or VCL params present is enough.
719 READ_BOOL_OR_RETURN(&data); // low_delay_hrd_flag
721 READ_BOOL_OR_RETURN(&data); // pic_struct_present_flag
722 READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
723 if (sps->bitstream_restriction_flag) {
724 READ_BOOL_OR_RETURN(&data); // motion_vectors_over_pic_boundaries_flag
725 READ_UE_OR_RETURN(&data); // max_bytes_per_pic_denom
726 READ_UE_OR_RETURN(&data); // max_bits_per_mb_denom
727 READ_UE_OR_RETURN(&data); // log2_max_mv_length_horizontal
728 READ_UE_OR_RETURN(&data); // log2_max_mv_length_vertical
729 READ_UE_OR_RETURN(&sps->max_num_reorder_frames);
730 READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
731 TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
732 IN_RANGE_OR_RETURN(
733 sps->max_num_reorder_frames, 0, sps->max_dec_frame_buffering);
736 return kOk;
739 static void FillDefaultSeqScalingLists(H264SPS* sps) {
740 for (int i = 0; i < 6; ++i)
741 for (int j = 0; j < kH264ScalingList4x4Length; ++j)
742 sps->scaling_list4x4[i][j] = 16;
744 for (int i = 0; i < 6; ++i)
745 for (int j = 0; j < kH264ScalingList8x8Length; ++j)
746 sps->scaling_list8x8[i][j] = 16;
749 H264Parser::Result H264Parser::ParseSPS(int* sps_id) {
750 // See 7.4.2.1.
751 int data;
752 Result res;
754 *sps_id = -1;
756 scoped_ptr<H264SPS> sps(new H264SPS());
758 READ_BITS_OR_RETURN(8, &sps->profile_idc);
759 READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
760 READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
761 READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
762 READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
763 READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
764 READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
765 READ_BITS_OR_RETURN(2, &data); // reserved_zero_2bits
766 READ_BITS_OR_RETURN(8, &sps->level_idc);
767 READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
768 TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
770 if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
771 sps->profile_idc == 122 || sps->profile_idc == 244 ||
772 sps->profile_idc == 44 || sps->profile_idc == 83 ||
773 sps->profile_idc == 86 || sps->profile_idc == 118 ||
774 sps->profile_idc == 128) {
775 READ_UE_OR_RETURN(&sps->chroma_format_idc);
776 TRUE_OR_RETURN(sps->chroma_format_idc < 4);
778 if (sps->chroma_format_idc == 3)
779 READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
781 READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
782 TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
784 READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
785 TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
787 READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
788 READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
790 if (sps->seq_scaling_matrix_present_flag) {
791 DVLOG(4) << "Scaling matrix present";
792 res = ParseSPSScalingLists(sps.get());
793 if (res != kOk)
794 return res;
795 } else {
796 FillDefaultSeqScalingLists(sps.get());
798 } else {
799 sps->chroma_format_idc = 1;
800 FillDefaultSeqScalingLists(sps.get());
803 if (sps->separate_colour_plane_flag)
804 sps->chroma_array_type = 0;
805 else
806 sps->chroma_array_type = sps->chroma_format_idc;
808 READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
809 TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
811 READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
812 TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
814 sps->expected_delta_per_pic_order_cnt_cycle = 0;
815 if (sps->pic_order_cnt_type == 0) {
816 READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
817 TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
818 } else if (sps->pic_order_cnt_type == 1) {
819 READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
820 READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
821 READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
822 READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
823 TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
825 for (int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
826 READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
827 sps->expected_delta_per_pic_order_cnt_cycle +=
828 sps->offset_for_ref_frame[i];
832 READ_UE_OR_RETURN(&sps->max_num_ref_frames);
833 READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
835 if (sps->gaps_in_frame_num_value_allowed_flag)
836 return kUnsupportedStream;
838 READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
839 READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
841 READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
842 if (!sps->frame_mbs_only_flag)
843 READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
845 READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
847 READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
848 if (sps->frame_cropping_flag) {
849 READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
850 READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
851 READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
852 READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
855 READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
856 if (sps->vui_parameters_present_flag) {
857 DVLOG(4) << "VUI parameters present";
858 res = ParseVUIParameters(sps.get());
859 if (res != kOk)
860 return res;
863 // If an SPS with the same id already exists, replace it.
864 *sps_id = sps->seq_parameter_set_id;
865 delete active_SPSes_[*sps_id];
866 active_SPSes_[*sps_id] = sps.release();
868 return kOk;
871 H264Parser::Result H264Parser::ParsePPS(int* pps_id) {
872 // See 7.4.2.2.
873 const H264SPS* sps;
874 Result res;
876 *pps_id = -1;
878 scoped_ptr<H264PPS> pps(new H264PPS());
880 READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
881 READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
882 TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
884 sps = GetSPS(pps->seq_parameter_set_id);
885 TRUE_OR_RETURN(sps);
887 READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
888 READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
890 READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
891 if (pps->num_slice_groups_minus1 > 1) {
892 DVLOG(1) << "Slice groups not supported";
893 return kUnsupportedStream;
896 READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
897 TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
899 READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
900 TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
902 READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
903 READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
904 TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
906 READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
907 IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
909 READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
910 IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
912 READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
913 IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
914 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
916 READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
917 READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
918 READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
920 if (br_.HasMoreRBSPData()) {
921 READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
922 READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
924 if (pps->pic_scaling_matrix_present_flag) {
925 DVLOG(4) << "Picture scaling matrix present";
926 res = ParsePPSScalingLists(*sps, pps.get());
927 if (res != kOk)
928 return res;
931 READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
934 // If a PPS with the same id already exists, replace it.
935 *pps_id = pps->pic_parameter_set_id;
936 delete active_PPSes_[*pps_id];
937 active_PPSes_[*pps_id] = pps.release();
939 return kOk;
942 H264Parser::Result H264Parser::ParseRefPicListModification(
943 int num_ref_idx_active_minus1,
944 H264ModificationOfPicNum* ref_list_mods) {
945 H264ModificationOfPicNum* pic_num_mod;
947 if (num_ref_idx_active_minus1 >= 32)
948 return kInvalidStream;
950 for (int i = 0; i < 32; ++i) {
951 pic_num_mod = &ref_list_mods[i];
952 READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
953 TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
955 switch (pic_num_mod->modification_of_pic_nums_idc) {
956 case 0:
957 case 1:
958 READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
959 break;
961 case 2:
962 READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
963 break;
965 case 3:
966 // Per spec, list cannot be empty.
967 if (i == 0)
968 return kInvalidStream;
969 return kOk;
971 default:
972 return kInvalidStream;
976 // If we got here, we didn't get loop end marker prematurely,
977 // so make sure it is there for our client.
978 int modification_of_pic_nums_idc;
979 READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
980 TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
982 return kOk;
985 H264Parser::Result H264Parser::ParseRefPicListModifications(
986 H264SliceHeader* shdr) {
987 Result res;
989 if (!shdr->IsISlice() && !shdr->IsSISlice()) {
990 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
991 if (shdr->ref_pic_list_modification_flag_l0) {
992 res = ParseRefPicListModification(shdr->num_ref_idx_l0_active_minus1,
993 shdr->ref_list_l0_modifications);
994 if (res != kOk)
995 return res;
999 if (shdr->IsBSlice()) {
1000 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
1001 if (shdr->ref_pic_list_modification_flag_l1) {
1002 res = ParseRefPicListModification(shdr->num_ref_idx_l1_active_minus1,
1003 shdr->ref_list_l1_modifications);
1004 if (res != kOk)
1005 return res;
1009 return kOk;
1012 H264Parser::Result H264Parser::ParseWeightingFactors(
1013 int num_ref_idx_active_minus1,
1014 int chroma_array_type,
1015 int luma_log2_weight_denom,
1016 int chroma_log2_weight_denom,
1017 H264WeightingFactors* w_facts) {
1019 int def_luma_weight = 1 << luma_log2_weight_denom;
1020 int def_chroma_weight = 1 << chroma_log2_weight_denom;
1022 for (int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
1023 READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag);
1024 if (w_facts->luma_weight_flag) {
1025 READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
1026 IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
1028 READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
1029 IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
1030 } else {
1031 w_facts->luma_weight[i] = def_luma_weight;
1032 w_facts->luma_offset[i] = 0;
1035 if (chroma_array_type != 0) {
1036 READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag);
1037 if (w_facts->chroma_weight_flag) {
1038 for (int j = 0; j < 2; ++j) {
1039 READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
1040 IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
1042 READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
1043 IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
1045 } else {
1046 for (int j = 0; j < 2; ++j) {
1047 w_facts->chroma_weight[i][j] = def_chroma_weight;
1048 w_facts->chroma_offset[i][j] = 0;
1054 return kOk;
1057 H264Parser::Result H264Parser::ParsePredWeightTable(const H264SPS& sps,
1058 H264SliceHeader* shdr) {
1059 READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
1060 TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
1062 if (sps.chroma_array_type != 0)
1063 READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
1064 TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
1066 Result res = ParseWeightingFactors(shdr->num_ref_idx_l0_active_minus1,
1067 sps.chroma_array_type,
1068 shdr->luma_log2_weight_denom,
1069 shdr->chroma_log2_weight_denom,
1070 &shdr->pred_weight_table_l0);
1071 if (res != kOk)
1072 return res;
1074 if (shdr->IsBSlice()) {
1075 res = ParseWeightingFactors(shdr->num_ref_idx_l1_active_minus1,
1076 sps.chroma_array_type,
1077 shdr->luma_log2_weight_denom,
1078 shdr->chroma_log2_weight_denom,
1079 &shdr->pred_weight_table_l1);
1080 if (res != kOk)
1081 return res;
1084 return kOk;
1087 H264Parser::Result H264Parser::ParseDecRefPicMarking(H264SliceHeader* shdr) {
1088 size_t bits_left_at_start = br_.NumBitsLeft();
1090 if (shdr->idr_pic_flag) {
1091 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
1092 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
1093 } else {
1094 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
1096 H264DecRefPicMarking* marking;
1097 if (shdr->adaptive_ref_pic_marking_mode_flag) {
1098 size_t i;
1099 for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) {
1100 marking = &shdr->ref_pic_marking[i];
1102 READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
1103 if (marking->memory_mgmnt_control_operation == 0)
1104 break;
1106 if (marking->memory_mgmnt_control_operation == 1 ||
1107 marking->memory_mgmnt_control_operation == 3)
1108 READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
1110 if (marking->memory_mgmnt_control_operation == 2)
1111 READ_UE_OR_RETURN(&marking->long_term_pic_num);
1113 if (marking->memory_mgmnt_control_operation == 3 ||
1114 marking->memory_mgmnt_control_operation == 6)
1115 READ_UE_OR_RETURN(&marking->long_term_frame_idx);
1117 if (marking->memory_mgmnt_control_operation == 4)
1118 READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
1120 if (marking->memory_mgmnt_control_operation > 6)
1121 return kInvalidStream;
1124 if (i == arraysize(shdr->ref_pic_marking)) {
1125 DVLOG(1) << "Ran out of dec ref pic marking fields";
1126 return kUnsupportedStream;
1131 shdr->dec_ref_pic_marking_bit_size = bits_left_at_start - br_.NumBitsLeft();
1132 return kOk;
1135 H264Parser::Result H264Parser::ParseSliceHeader(const H264NALU& nalu,
1136 H264SliceHeader* shdr) {
1137 // See 7.4.3.
1138 const H264SPS* sps;
1139 const H264PPS* pps;
1140 Result res;
1142 memset(shdr, 0, sizeof(*shdr));
1144 shdr->idr_pic_flag = (nalu.nal_unit_type == 5);
1145 shdr->nal_ref_idc = nalu.nal_ref_idc;
1146 shdr->nalu_data = nalu.data;
1147 shdr->nalu_size = nalu.size;
1149 READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
1150 READ_UE_OR_RETURN(&shdr->slice_type);
1151 TRUE_OR_RETURN(shdr->slice_type < 10);
1153 READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
1155 pps = GetPPS(shdr->pic_parameter_set_id);
1156 TRUE_OR_RETURN(pps);
1158 sps = GetSPS(pps->seq_parameter_set_id);
1159 TRUE_OR_RETURN(sps);
1161 if (sps->separate_colour_plane_flag) {
1162 DVLOG(1) << "Interlaced streams not supported";
1163 return kUnsupportedStream;
1166 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1167 if (!sps->frame_mbs_only_flag) {
1168 READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1169 if (shdr->field_pic_flag) {
1170 DVLOG(1) << "Interlaced streams not supported";
1171 return kUnsupportedStream;
1175 if (shdr->idr_pic_flag)
1176 READ_UE_OR_RETURN(&shdr->idr_pic_id);
1178 size_t bits_left_at_pic_order_cnt_start = br_.NumBitsLeft();
1179 if (sps->pic_order_cnt_type == 0) {
1180 READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1181 &shdr->pic_order_cnt_lsb);
1182 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1183 !shdr->field_pic_flag)
1184 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1187 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1188 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt0);
1189 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1190 !shdr->field_pic_flag)
1191 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt1);
1194 shdr->pic_order_cnt_bit_size =
1195 bits_left_at_pic_order_cnt_start - br_.NumBitsLeft();
1197 if (pps->redundant_pic_cnt_present_flag) {
1198 READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1199 TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1202 if (shdr->IsBSlice())
1203 READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1205 if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1206 READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1207 if (shdr->num_ref_idx_active_override_flag) {
1208 READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1209 if (shdr->IsBSlice())
1210 READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1211 } else {
1212 shdr->num_ref_idx_l0_active_minus1 =
1213 pps->num_ref_idx_l0_default_active_minus1;
1214 if (shdr->IsBSlice()) {
1215 shdr->num_ref_idx_l1_active_minus1 =
1216 pps->num_ref_idx_l1_default_active_minus1;
1220 if (shdr->field_pic_flag) {
1221 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1222 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1223 } else {
1224 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1225 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1228 if (nalu.nal_unit_type == H264NALU::kCodedSliceExtension) {
1229 return kUnsupportedStream;
1230 } else {
1231 res = ParseRefPicListModifications(shdr);
1232 if (res != kOk)
1233 return res;
1236 if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1237 (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1238 res = ParsePredWeightTable(*sps, shdr);
1239 if (res != kOk)
1240 return res;
1243 if (nalu.nal_ref_idc != 0) {
1244 res = ParseDecRefPicMarking(shdr);
1245 if (res != kOk)
1246 return res;
1249 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1250 !shdr->IsSISlice()) {
1251 READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1252 TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1255 READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1257 if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1258 if (shdr->IsSPSlice())
1259 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1260 READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1263 if (pps->deblocking_filter_control_present_flag) {
1264 READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1265 TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1267 if (shdr->disable_deblocking_filter_idc != 1) {
1268 READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1269 IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1271 READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1272 IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1276 if (pps->num_slice_groups_minus1 > 0) {
1277 DVLOG(1) << "Slice groups not supported";
1278 return kUnsupportedStream;
1281 size_t epb = br_.NumEmulationPreventionBytesRead();
1282 shdr->header_bit_size = (shdr->nalu_size - epb) * 8 - br_.NumBitsLeft();
1284 return kOk;
1287 H264Parser::Result H264Parser::ParseSEI(H264SEIMessage* sei_msg) {
1288 int byte;
1290 memset(sei_msg, 0, sizeof(*sei_msg));
1292 READ_BITS_OR_RETURN(8, &byte);
1293 while (byte == 0xff) {
1294 sei_msg->type += 255;
1295 READ_BITS_OR_RETURN(8, &byte);
1297 sei_msg->type += byte;
1299 READ_BITS_OR_RETURN(8, &byte);
1300 while (byte == 0xff) {
1301 sei_msg->payload_size += 255;
1302 READ_BITS_OR_RETURN(8, &byte);
1304 sei_msg->payload_size += byte;
1306 DVLOG(4) << "Found SEI message type: " << sei_msg->type
1307 << " payload size: " << sei_msg->payload_size;
1309 switch (sei_msg->type) {
1310 case H264SEIMessage::kSEIRecoveryPoint:
1311 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1312 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1313 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1314 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1315 break;
1317 default:
1318 DVLOG(4) << "Unsupported SEI message";
1319 break;
1322 return kOk;
1325 } // namespace media