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/filters/h264_parser.h"
13 bool H264SliceHeader::IsPSlice() const {
14 return (slice_type
% 5 == kPSlice
);
17 bool H264SliceHeader::IsBSlice() const {
18 return (slice_type
% 5 == kBSlice
);
21 bool H264SliceHeader::IsISlice() const {
22 return (slice_type
% 5 == kISlice
);
25 bool H264SliceHeader::IsSPSlice() const {
26 return (slice_type
% 5 == kSPSlice
);
29 bool H264SliceHeader::IsSISlice() const {
30 return (slice_type
% 5 == kSISlice
);
33 H264NALU::H264NALU() {
34 memset(this, 0, sizeof(*this));
38 memset(this, 0, sizeof(*this));
42 memset(this, 0, sizeof(*this));
45 H264SliceHeader::H264SliceHeader() {
46 memset(this, 0, sizeof(*this));
49 H264SEIMessage::H264SEIMessage() {
50 memset(this, 0, sizeof(*this));
53 #define READ_BITS_OR_RETURN(num_bits, out) \
56 if (!br_.ReadBits(num_bits, &_out)) { \
58 << "Error in stream: unexpected EOS while trying to read " #out; \
59 return kInvalidStream; \
64 #define READ_BOOL_OR_RETURN(out) \
67 if (!br_.ReadBits(1, &_out)) { \
69 << "Error in stream: unexpected EOS while trying to read " #out; \
70 return kInvalidStream; \
75 #define READ_UE_OR_RETURN(out) \
77 if (ReadUE(out) != kOk) { \
78 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
79 return kInvalidStream; \
83 #define READ_SE_OR_RETURN(out) \
85 if (ReadSE(out) != kOk) { \
86 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
87 return kInvalidStream; \
91 #define IN_RANGE_OR_RETURN(val, min, max) \
93 if ((val) < (min) || (val) > (max)) { \
94 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
95 << " in range [" << (min) << ":" << (max) << "]" \
96 << " found " << (val) << " instead"; \
97 return kInvalidStream; \
101 #define TRUE_OR_RETURN(a) \
104 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
105 return kInvalidStream; \
110 // VUI parameters: Table E-1 "Meaning of sample aspect ratio indicator"
111 static const int kTableSarWidth
[] = {
112 0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
114 static const int kTableSarHeight
[] = {
115 0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
117 COMPILE_ASSERT(arraysize(kTableSarWidth
) == arraysize(kTableSarHeight
),
118 sar_tables_must_have_same_size
);
120 H264Parser::H264Parser() {
124 H264Parser::~H264Parser() {
125 STLDeleteValues(&active_SPSes_
);
126 STLDeleteValues(&active_PPSes_
);
129 void H264Parser::Reset() {
134 void H264Parser::SetStream(const uint8
* stream
, off_t stream_size
) {
136 DCHECK_GT(stream_size
, 0);
139 bytes_left_
= stream_size
;
142 const H264PPS
* H264Parser::GetPPS(int pps_id
) {
143 return active_PPSes_
[pps_id
];
146 const H264SPS
* H264Parser::GetSPS(int sps_id
) {
147 return active_SPSes_
[sps_id
];
150 static inline bool IsStartCode(const uint8
* data
) {
151 return data
[0] == 0x00 && data
[1] == 0x00 && data
[2] == 0x01;
155 bool H264Parser::FindStartCode(const uint8
* data
, off_t data_size
,
156 off_t
* offset
, off_t
* start_code_size
) {
157 DCHECK_GE(data_size
, 0);
158 off_t bytes_left
= data_size
;
160 while (bytes_left
>= 3) {
161 if (IsStartCode(data
)) {
162 // Found three-byte start code, set pointer at its beginning.
163 *offset
= data_size
- bytes_left
;
164 *start_code_size
= 3;
166 // If there is a zero byte before this start code,
167 // then it's actually a four-byte start code, so backtrack one byte.
168 if (*offset
> 0 && *(data
- 1) == 0x00) {
170 ++(*start_code_size
);
180 // End of data: offset is pointing to the first byte that was not considered
181 // as a possible start of a start code.
182 // Note: there is no security issue when receiving a negative |data_size|
183 // since in this case, |bytes_left| is equal to |data_size| and thus
184 // |*offset| is equal to 0 (valid offset).
185 *offset
= data_size
- bytes_left
;
186 *start_code_size
= 0;
190 bool H264Parser::LocateNALU(off_t
* nalu_size
, off_t
* start_code_size
) {
191 // Find the start code of next NALU.
192 off_t nalu_start_off
= 0;
193 off_t annexb_start_code_size
= 0;
194 if (!FindStartCode(stream_
, bytes_left_
,
195 &nalu_start_off
, &annexb_start_code_size
)) {
196 DVLOG(4) << "Could not find start code, end of stream?";
200 // Move the stream to the beginning of the NALU (pointing at the start code).
201 stream_
+= nalu_start_off
;
202 bytes_left_
-= nalu_start_off
;
204 const uint8
* nalu_data
= stream_
+ annexb_start_code_size
;
205 off_t max_nalu_data_size
= bytes_left_
- annexb_start_code_size
;
206 if (max_nalu_data_size
<= 0) {
207 DVLOG(3) << "End of stream";
211 // Find the start code of next NALU;
212 // if successful, |nalu_size_without_start_code| is the number of bytes from
213 // after previous start code to before this one;
214 // if next start code is not found, it is still a valid NALU since there
215 // are some bytes left after the first start code: all the remaining bytes
216 // belong to the current NALU.
217 off_t next_start_code_size
= 0;
218 off_t nalu_size_without_start_code
= 0;
219 if (!FindStartCode(nalu_data
, max_nalu_data_size
,
220 &nalu_size_without_start_code
, &next_start_code_size
)) {
221 nalu_size_without_start_code
= max_nalu_data_size
;
223 *nalu_size
= nalu_size_without_start_code
+ annexb_start_code_size
;
224 *start_code_size
= annexb_start_code_size
;
228 H264Parser::Result
H264Parser::ReadUE(int* val
) {
233 // Count the number of contiguous zero bits.
235 READ_BITS_OR_RETURN(1, &bit
);
240 return kInvalidStream
;
242 // Calculate exp-Golomb code value of size num_bits.
243 *val
= (1 << num_bits
) - 1;
246 READ_BITS_OR_RETURN(num_bits
, &rest
);
253 H264Parser::Result
H264Parser::ReadSE(int* val
) {
257 // See Chapter 9 in the spec.
270 H264Parser::Result
H264Parser::AdvanceToNextNALU(H264NALU
* nalu
) {
271 off_t start_code_size
;
272 off_t nalu_size_with_start_code
;
273 if (!LocateNALU(&nalu_size_with_start_code
, &start_code_size
)) {
274 DVLOG(4) << "Could not find next NALU, bytes left in stream: "
279 nalu
->data
= stream_
+ start_code_size
;
280 nalu
->size
= nalu_size_with_start_code
- start_code_size
;
281 DVLOG(4) << "NALU found: size=" << nalu_size_with_start_code
;
283 // Initialize bit reader at the start of found NALU.
284 if (!br_
.Initialize(nalu
->data
, nalu
->size
))
287 // Move parser state to after this NALU, so next time AdvanceToNextNALU
288 // is called, we will effectively be skipping it;
289 // other parsing functions will use the position saved
290 // in bit reader for parsing, so we don't have to remember it here.
291 stream_
+= nalu_size_with_start_code
;
292 bytes_left_
-= nalu_size_with_start_code
;
294 // Read NALU header, skip the forbidden_zero_bit, but check for it.
296 READ_BITS_OR_RETURN(1, &data
);
297 TRUE_OR_RETURN(data
== 0);
299 READ_BITS_OR_RETURN(2, &nalu
->nal_ref_idc
);
300 READ_BITS_OR_RETURN(5, &nalu
->nal_unit_type
);
302 DVLOG(4) << "NALU type: " << static_cast<int>(nalu
->nal_unit_type
)
303 << " at: " << reinterpret_cast<const void*>(nalu
->data
)
304 << " size: " << nalu
->size
305 << " ref: " << static_cast<int>(nalu
->nal_ref_idc
);
310 // Default scaling lists (per spec).
311 static const int kDefault4x4Intra
[kH264ScalingList4x4Length
] = {
312 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
314 static const int kDefault4x4Inter
[kH264ScalingList4x4Length
] = {
315 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
317 static const int kDefault8x8Intra
[kH264ScalingList8x8Length
] = {
318 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
319 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
320 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
321 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
323 static const int kDefault8x8Inter
[kH264ScalingList8x8Length
] = {
324 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
325 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
326 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
327 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
329 static inline void DefaultScalingList4x4(
331 int scaling_list4x4
[][kH264ScalingList4x4Length
]) {
335 memcpy(scaling_list4x4
[i
], kDefault4x4Intra
, sizeof(kDefault4x4Intra
));
337 memcpy(scaling_list4x4
[i
], kDefault4x4Inter
, sizeof(kDefault4x4Inter
));
340 static inline void DefaultScalingList8x8(
342 int scaling_list8x8
[][kH264ScalingList8x8Length
]) {
346 memcpy(scaling_list8x8
[i
], kDefault8x8Intra
, sizeof(kDefault8x8Intra
));
348 memcpy(scaling_list8x8
[i
], kDefault8x8Inter
, sizeof(kDefault8x8Inter
));
351 static void FallbackScalingList4x4(
353 const int default_scaling_list_intra
[],
354 const int default_scaling_list_inter
[],
355 int scaling_list4x4
[][kH264ScalingList4x4Length
]) {
356 static const int kScalingList4x4ByteSize
=
357 sizeof(scaling_list4x4
[0][0]) * kH264ScalingList4x4Length
;
361 memcpy(scaling_list4x4
[i
], default_scaling_list_intra
,
362 kScalingList4x4ByteSize
);
366 memcpy(scaling_list4x4
[i
], scaling_list4x4
[0], kScalingList4x4ByteSize
);
370 memcpy(scaling_list4x4
[i
], scaling_list4x4
[1], kScalingList4x4ByteSize
);
374 memcpy(scaling_list4x4
[i
], default_scaling_list_inter
,
375 kScalingList4x4ByteSize
);
379 memcpy(scaling_list4x4
[i
], scaling_list4x4
[3], kScalingList4x4ByteSize
);
383 memcpy(scaling_list4x4
[i
], scaling_list4x4
[4], kScalingList4x4ByteSize
);
392 static void FallbackScalingList8x8(
394 const int default_scaling_list_intra
[],
395 const int default_scaling_list_inter
[],
396 int scaling_list8x8
[][kH264ScalingList8x8Length
]) {
397 static const int kScalingList8x8ByteSize
=
398 sizeof(scaling_list8x8
[0][0]) * kH264ScalingList8x8Length
;
402 memcpy(scaling_list8x8
[i
], default_scaling_list_intra
,
403 kScalingList8x8ByteSize
);
407 memcpy(scaling_list8x8
[i
], default_scaling_list_inter
,
408 kScalingList8x8ByteSize
);
412 memcpy(scaling_list8x8
[i
], scaling_list8x8
[0], kScalingList8x8ByteSize
);
416 memcpy(scaling_list8x8
[i
], scaling_list8x8
[1], kScalingList8x8ByteSize
);
420 memcpy(scaling_list8x8
[i
], scaling_list8x8
[2], kScalingList8x8ByteSize
);
424 memcpy(scaling_list8x8
[i
], scaling_list8x8
[3], kScalingList8x8ByteSize
);
433 H264Parser::Result
H264Parser::ParseScalingList(int size
,
436 // See chapter 7.3.2.1.1.1.
441 *use_default
= false;
443 for (int j
= 0; j
< size
; ++j
) {
444 if (next_scale
!= 0) {
445 READ_SE_OR_RETURN(&delta_scale
);
446 IN_RANGE_OR_RETURN(delta_scale
, -128, 127);
447 next_scale
= (last_scale
+ delta_scale
+ 256) & 0xff;
449 if (j
== 0 && next_scale
== 0) {
455 scaling_list
[j
] = (next_scale
== 0) ? last_scale
: next_scale
;
456 last_scale
= scaling_list
[j
];
462 H264Parser::Result
H264Parser::ParseSPSScalingLists(H264SPS
* sps
) {
464 bool seq_scaling_list_present_flag
;
468 // Parse scaling_list4x4.
469 for (int i
= 0; i
< 6; ++i
) {
470 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag
);
472 if (seq_scaling_list_present_flag
) {
473 res
= ParseScalingList(arraysize(sps
->scaling_list4x4
[i
]),
474 sps
->scaling_list4x4
[i
],
480 DefaultScalingList4x4(i
, sps
->scaling_list4x4
);
483 FallbackScalingList4x4(
484 i
, kDefault4x4Intra
, kDefault4x4Inter
, sps
->scaling_list4x4
);
488 // Parse scaling_list8x8.
489 for (int i
= 0; i
< ((sps
->chroma_format_idc
!= 3) ? 2 : 6); ++i
) {
490 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag
);
492 if (seq_scaling_list_present_flag
) {
493 res
= ParseScalingList(arraysize(sps
->scaling_list8x8
[i
]),
494 sps
->scaling_list8x8
[i
],
500 DefaultScalingList8x8(i
, sps
->scaling_list8x8
);
503 FallbackScalingList8x8(
504 i
, kDefault8x8Intra
, kDefault8x8Inter
, sps
->scaling_list8x8
);
511 H264Parser::Result
H264Parser::ParsePPSScalingLists(const H264SPS
& sps
,
514 bool pic_scaling_list_present_flag
;
518 for (int i
= 0; i
< 6; ++i
) {
519 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag
);
521 if (pic_scaling_list_present_flag
) {
522 res
= ParseScalingList(arraysize(pps
->scaling_list4x4
[i
]),
523 pps
->scaling_list4x4
[i
],
529 DefaultScalingList4x4(i
, pps
->scaling_list4x4
);
532 if (sps
.seq_scaling_matrix_present_flag
) {
533 // Table 7-2 fallback rule A in spec.
534 FallbackScalingList4x4(
535 i
, kDefault4x4Intra
, kDefault4x4Inter
, pps
->scaling_list4x4
);
537 // Table 7-2 fallback rule B in spec.
538 FallbackScalingList4x4(i
,
539 sps
.scaling_list4x4
[0],
540 sps
.scaling_list4x4
[3],
541 pps
->scaling_list4x4
);
546 if (pps
->transform_8x8_mode_flag
) {
547 for (int i
= 0; i
< ((sps
.chroma_format_idc
!= 3) ? 2 : 6); ++i
) {
548 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag
);
550 if (pic_scaling_list_present_flag
) {
551 res
= ParseScalingList(arraysize(pps
->scaling_list8x8
[i
]),
552 pps
->scaling_list8x8
[i
],
558 DefaultScalingList8x8(i
, pps
->scaling_list8x8
);
561 if (sps
.seq_scaling_matrix_present_flag
) {
562 // Table 7-2 fallback rule A in spec.
563 FallbackScalingList8x8(
564 i
, kDefault8x8Intra
, kDefault8x8Inter
, pps
->scaling_list8x8
);
566 // Table 7-2 fallback rule B in spec.
567 FallbackScalingList8x8(i
,
568 sps
.scaling_list8x8
[0],
569 sps
.scaling_list8x8
[1],
570 pps
->scaling_list8x8
);
578 H264Parser::Result
H264Parser::ParseAndIgnoreHRDParameters(
579 bool* hrd_parameters_present
) {
581 READ_BOOL_OR_RETURN(&data
); // {nal,vcl}_hrd_parameters_present_flag
585 *hrd_parameters_present
= true;
588 READ_UE_OR_RETURN(&cpb_cnt_minus1
);
589 IN_RANGE_OR_RETURN(cpb_cnt_minus1
, 0, 31);
590 READ_BITS_OR_RETURN(8, &data
); // bit_rate_scale, cpb_size_scale
591 for (int i
= 0; i
<= cpb_cnt_minus1
; ++i
) {
592 READ_UE_OR_RETURN(&data
); // bit_rate_value_minus1[i]
593 READ_UE_OR_RETURN(&data
); // cpb_size_value_minus1[i]
594 READ_BOOL_OR_RETURN(&data
); // cbr_flag
596 READ_BITS_OR_RETURN(20, &data
); // cpb/dpb delays, etc.
601 H264Parser::Result
H264Parser::ParseVUIParameters(H264SPS
* sps
) {
602 bool aspect_ratio_info_present_flag
;
603 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag
);
604 if (aspect_ratio_info_present_flag
) {
605 int aspect_ratio_idc
;
606 READ_BITS_OR_RETURN(8, &aspect_ratio_idc
);
607 if (aspect_ratio_idc
== H264SPS::kExtendedSar
) {
608 READ_BITS_OR_RETURN(16, &sps
->sar_width
);
609 READ_BITS_OR_RETURN(16, &sps
->sar_height
);
611 const int max_aspect_ratio_idc
= arraysize(kTableSarWidth
) - 1;
612 IN_RANGE_OR_RETURN(aspect_ratio_idc
, 0, max_aspect_ratio_idc
);
613 sps
->sar_width
= kTableSarWidth
[aspect_ratio_idc
];
614 sps
->sar_height
= kTableSarHeight
[aspect_ratio_idc
];
619 // Read and ignore overscan and video signal type info.
620 READ_BOOL_OR_RETURN(&data
); // overscan_info_present_flag
622 READ_BOOL_OR_RETURN(&data
); // overscan_appropriate_flag
624 READ_BOOL_OR_RETURN(&data
); // video_signal_type_present_flag
626 READ_BITS_OR_RETURN(3, &data
); // video_format
627 READ_BOOL_OR_RETURN(&data
); // video_full_range_flag
628 READ_BOOL_OR_RETURN(&data
); // colour_description_present_flag
630 READ_BITS_OR_RETURN(24, &data
); // color description syntax elements
633 READ_BOOL_OR_RETURN(&data
); // chroma_loc_info_present_flag
635 READ_UE_OR_RETURN(&data
); // chroma_sample_loc_type_top_field
636 READ_UE_OR_RETURN(&data
); // chroma_sample_loc_type_bottom_field
639 // Read and ignore timing info.
640 READ_BOOL_OR_RETURN(&data
); // timing_info_present_flag
642 READ_BITS_OR_RETURN(16, &data
); // num_units_in_tick
643 READ_BITS_OR_RETURN(16, &data
); // num_units_in_tick
644 READ_BITS_OR_RETURN(16, &data
); // time_scale
645 READ_BITS_OR_RETURN(16, &data
); // time_scale
646 READ_BOOL_OR_RETURN(&data
); // fixed_frame_rate_flag
649 // Read and ignore NAL HRD parameters, if present.
650 bool hrd_parameters_present
= false;
651 Result res
= ParseAndIgnoreHRDParameters(&hrd_parameters_present
);
655 // Read and ignore VCL HRD parameters, if present.
656 res
= ParseAndIgnoreHRDParameters(&hrd_parameters_present
);
660 if (hrd_parameters_present
) // One of NAL or VCL params present is enough.
661 READ_BOOL_OR_RETURN(&data
); // low_delay_hrd_flag
663 READ_BOOL_OR_RETURN(&data
); // pic_struct_present_flag
664 READ_BOOL_OR_RETURN(&sps
->bitstream_restriction_flag
);
665 if (sps
->bitstream_restriction_flag
) {
666 READ_BOOL_OR_RETURN(&data
); // motion_vectors_over_pic_boundaries_flag
667 READ_UE_OR_RETURN(&data
); // max_bytes_per_pic_denom
668 READ_UE_OR_RETURN(&data
); // max_bits_per_mb_denom
669 READ_UE_OR_RETURN(&data
); // log2_max_mv_length_horizontal
670 READ_UE_OR_RETURN(&data
); // log2_max_mv_length_vertical
671 READ_UE_OR_RETURN(&sps
->max_num_reorder_frames
);
672 READ_UE_OR_RETURN(&sps
->max_dec_frame_buffering
);
673 TRUE_OR_RETURN(sps
->max_dec_frame_buffering
>= sps
->max_num_ref_frames
);
675 sps
->max_num_reorder_frames
, 0, sps
->max_dec_frame_buffering
);
681 static void FillDefaultSeqScalingLists(H264SPS
* sps
) {
682 for (int i
= 0; i
< 6; ++i
)
683 for (int j
= 0; j
< kH264ScalingList4x4Length
; ++j
)
684 sps
->scaling_list4x4
[i
][j
] = 16;
686 for (int i
= 0; i
< 6; ++i
)
687 for (int j
= 0; j
< kH264ScalingList8x8Length
; ++j
)
688 sps
->scaling_list8x8
[i
][j
] = 16;
691 H264Parser::Result
H264Parser::ParseSPS(int* sps_id
) {
698 scoped_ptr
<H264SPS
> sps(new H264SPS());
700 READ_BITS_OR_RETURN(8, &sps
->profile_idc
);
701 READ_BOOL_OR_RETURN(&sps
->constraint_set0_flag
);
702 READ_BOOL_OR_RETURN(&sps
->constraint_set1_flag
);
703 READ_BOOL_OR_RETURN(&sps
->constraint_set2_flag
);
704 READ_BOOL_OR_RETURN(&sps
->constraint_set3_flag
);
705 READ_BOOL_OR_RETURN(&sps
->constraint_set4_flag
);
706 READ_BOOL_OR_RETURN(&sps
->constraint_set5_flag
);
707 READ_BITS_OR_RETURN(2, &data
); // reserved_zero_2bits
708 READ_BITS_OR_RETURN(8, &sps
->level_idc
);
709 READ_UE_OR_RETURN(&sps
->seq_parameter_set_id
);
710 TRUE_OR_RETURN(sps
->seq_parameter_set_id
< 32);
712 if (sps
->profile_idc
== 100 || sps
->profile_idc
== 110 ||
713 sps
->profile_idc
== 122 || sps
->profile_idc
== 244 ||
714 sps
->profile_idc
== 44 || sps
->profile_idc
== 83 ||
715 sps
->profile_idc
== 86 || sps
->profile_idc
== 118 ||
716 sps
->profile_idc
== 128) {
717 READ_UE_OR_RETURN(&sps
->chroma_format_idc
);
718 TRUE_OR_RETURN(sps
->chroma_format_idc
< 4);
720 if (sps
->chroma_format_idc
== 3)
721 READ_BOOL_OR_RETURN(&sps
->separate_colour_plane_flag
);
723 READ_UE_OR_RETURN(&sps
->bit_depth_luma_minus8
);
724 TRUE_OR_RETURN(sps
->bit_depth_luma_minus8
< 7);
726 READ_UE_OR_RETURN(&sps
->bit_depth_chroma_minus8
);
727 TRUE_OR_RETURN(sps
->bit_depth_chroma_minus8
< 7);
729 READ_BOOL_OR_RETURN(&sps
->qpprime_y_zero_transform_bypass_flag
);
730 READ_BOOL_OR_RETURN(&sps
->seq_scaling_matrix_present_flag
);
732 if (sps
->seq_scaling_matrix_present_flag
) {
733 DVLOG(4) << "Scaling matrix present";
734 res
= ParseSPSScalingLists(sps
.get());
738 FillDefaultSeqScalingLists(sps
.get());
741 sps
->chroma_format_idc
= 1;
742 FillDefaultSeqScalingLists(sps
.get());
745 if (sps
->separate_colour_plane_flag
)
746 sps
->chroma_array_type
= 0;
748 sps
->chroma_array_type
= sps
->chroma_format_idc
;
750 READ_UE_OR_RETURN(&sps
->log2_max_frame_num_minus4
);
751 TRUE_OR_RETURN(sps
->log2_max_frame_num_minus4
< 13);
753 READ_UE_OR_RETURN(&sps
->pic_order_cnt_type
);
754 TRUE_OR_RETURN(sps
->pic_order_cnt_type
< 3);
756 sps
->expected_delta_per_pic_order_cnt_cycle
= 0;
757 if (sps
->pic_order_cnt_type
== 0) {
758 READ_UE_OR_RETURN(&sps
->log2_max_pic_order_cnt_lsb_minus4
);
759 TRUE_OR_RETURN(sps
->log2_max_pic_order_cnt_lsb_minus4
< 13);
760 } else if (sps
->pic_order_cnt_type
== 1) {
761 READ_BOOL_OR_RETURN(&sps
->delta_pic_order_always_zero_flag
);
762 READ_SE_OR_RETURN(&sps
->offset_for_non_ref_pic
);
763 READ_SE_OR_RETURN(&sps
->offset_for_top_to_bottom_field
);
764 READ_UE_OR_RETURN(&sps
->num_ref_frames_in_pic_order_cnt_cycle
);
765 TRUE_OR_RETURN(sps
->num_ref_frames_in_pic_order_cnt_cycle
< 255);
767 for (int i
= 0; i
< sps
->num_ref_frames_in_pic_order_cnt_cycle
; ++i
) {
768 READ_SE_OR_RETURN(&sps
->offset_for_ref_frame
[i
]);
769 sps
->expected_delta_per_pic_order_cnt_cycle
+=
770 sps
->offset_for_ref_frame
[i
];
774 READ_UE_OR_RETURN(&sps
->max_num_ref_frames
);
775 READ_BOOL_OR_RETURN(&sps
->gaps_in_frame_num_value_allowed_flag
);
777 if (sps
->gaps_in_frame_num_value_allowed_flag
)
778 return kUnsupportedStream
;
780 READ_UE_OR_RETURN(&sps
->pic_width_in_mbs_minus1
);
781 READ_UE_OR_RETURN(&sps
->pic_height_in_map_units_minus1
);
783 READ_BOOL_OR_RETURN(&sps
->frame_mbs_only_flag
);
784 if (!sps
->frame_mbs_only_flag
)
785 READ_BOOL_OR_RETURN(&sps
->mb_adaptive_frame_field_flag
);
787 READ_BOOL_OR_RETURN(&sps
->direct_8x8_inference_flag
);
789 READ_BOOL_OR_RETURN(&sps
->frame_cropping_flag
);
790 if (sps
->frame_cropping_flag
) {
791 READ_UE_OR_RETURN(&sps
->frame_crop_left_offset
);
792 READ_UE_OR_RETURN(&sps
->frame_crop_right_offset
);
793 READ_UE_OR_RETURN(&sps
->frame_crop_top_offset
);
794 READ_UE_OR_RETURN(&sps
->frame_crop_bottom_offset
);
797 READ_BOOL_OR_RETURN(&sps
->vui_parameters_present_flag
);
798 if (sps
->vui_parameters_present_flag
) {
799 DVLOG(4) << "VUI parameters present";
800 res
= ParseVUIParameters(sps
.get());
805 // If an SPS with the same id already exists, replace it.
806 *sps_id
= sps
->seq_parameter_set_id
;
807 delete active_SPSes_
[*sps_id
];
808 active_SPSes_
[*sps_id
] = sps
.release();
813 H264Parser::Result
H264Parser::ParsePPS(int* pps_id
) {
820 scoped_ptr
<H264PPS
> pps(new H264PPS());
822 READ_UE_OR_RETURN(&pps
->pic_parameter_set_id
);
823 READ_UE_OR_RETURN(&pps
->seq_parameter_set_id
);
824 TRUE_OR_RETURN(pps
->seq_parameter_set_id
< 32);
826 sps
= GetSPS(pps
->seq_parameter_set_id
);
829 READ_BOOL_OR_RETURN(&pps
->entropy_coding_mode_flag
);
830 READ_BOOL_OR_RETURN(&pps
->bottom_field_pic_order_in_frame_present_flag
);
832 READ_UE_OR_RETURN(&pps
->num_slice_groups_minus1
);
833 if (pps
->num_slice_groups_minus1
> 1) {
834 DVLOG(1) << "Slice groups not supported";
835 return kUnsupportedStream
;
838 READ_UE_OR_RETURN(&pps
->num_ref_idx_l0_default_active_minus1
);
839 TRUE_OR_RETURN(pps
->num_ref_idx_l0_default_active_minus1
< 32);
841 READ_UE_OR_RETURN(&pps
->num_ref_idx_l1_default_active_minus1
);
842 TRUE_OR_RETURN(pps
->num_ref_idx_l1_default_active_minus1
< 32);
844 READ_BOOL_OR_RETURN(&pps
->weighted_pred_flag
);
845 READ_BITS_OR_RETURN(2, &pps
->weighted_bipred_idc
);
846 TRUE_OR_RETURN(pps
->weighted_bipred_idc
< 3);
848 READ_SE_OR_RETURN(&pps
->pic_init_qp_minus26
);
849 IN_RANGE_OR_RETURN(pps
->pic_init_qp_minus26
, -26, 25);
851 READ_SE_OR_RETURN(&pps
->pic_init_qs_minus26
);
852 IN_RANGE_OR_RETURN(pps
->pic_init_qs_minus26
, -26, 25);
854 READ_SE_OR_RETURN(&pps
->chroma_qp_index_offset
);
855 IN_RANGE_OR_RETURN(pps
->chroma_qp_index_offset
, -12, 12);
856 pps
->second_chroma_qp_index_offset
= pps
->chroma_qp_index_offset
;
858 READ_BOOL_OR_RETURN(&pps
->deblocking_filter_control_present_flag
);
859 READ_BOOL_OR_RETURN(&pps
->constrained_intra_pred_flag
);
860 READ_BOOL_OR_RETURN(&pps
->redundant_pic_cnt_present_flag
);
862 if (br_
.HasMoreRBSPData()) {
863 READ_BOOL_OR_RETURN(&pps
->transform_8x8_mode_flag
);
864 READ_BOOL_OR_RETURN(&pps
->pic_scaling_matrix_present_flag
);
866 if (pps
->pic_scaling_matrix_present_flag
) {
867 DVLOG(4) << "Picture scaling matrix present";
868 res
= ParsePPSScalingLists(*sps
, pps
.get());
873 READ_SE_OR_RETURN(&pps
->second_chroma_qp_index_offset
);
876 // If a PPS with the same id already exists, replace it.
877 *pps_id
= pps
->pic_parameter_set_id
;
878 delete active_PPSes_
[*pps_id
];
879 active_PPSes_
[*pps_id
] = pps
.release();
884 H264Parser::Result
H264Parser::ParseRefPicListModification(
885 int num_ref_idx_active_minus1
,
886 H264ModificationOfPicNum
* ref_list_mods
) {
887 H264ModificationOfPicNum
* pic_num_mod
;
889 if (num_ref_idx_active_minus1
>= 32)
890 return kInvalidStream
;
892 for (int i
= 0; i
< 32; ++i
) {
893 pic_num_mod
= &ref_list_mods
[i
];
894 READ_UE_OR_RETURN(&pic_num_mod
->modification_of_pic_nums_idc
);
895 TRUE_OR_RETURN(pic_num_mod
->modification_of_pic_nums_idc
< 4);
897 switch (pic_num_mod
->modification_of_pic_nums_idc
) {
900 READ_UE_OR_RETURN(&pic_num_mod
->abs_diff_pic_num_minus1
);
904 READ_UE_OR_RETURN(&pic_num_mod
->long_term_pic_num
);
908 // Per spec, list cannot be empty.
910 return kInvalidStream
;
914 return kInvalidStream
;
918 // If we got here, we didn't get loop end marker prematurely,
919 // so make sure it is there for our client.
920 int modification_of_pic_nums_idc
;
921 READ_UE_OR_RETURN(&modification_of_pic_nums_idc
);
922 TRUE_OR_RETURN(modification_of_pic_nums_idc
== 3);
927 H264Parser::Result
H264Parser::ParseRefPicListModifications(
928 H264SliceHeader
* shdr
) {
931 if (!shdr
->IsISlice() && !shdr
->IsSISlice()) {
932 READ_BOOL_OR_RETURN(&shdr
->ref_pic_list_modification_flag_l0
);
933 if (shdr
->ref_pic_list_modification_flag_l0
) {
934 res
= ParseRefPicListModification(shdr
->num_ref_idx_l0_active_minus1
,
935 shdr
->ref_list_l0_modifications
);
941 if (shdr
->IsBSlice()) {
942 READ_BOOL_OR_RETURN(&shdr
->ref_pic_list_modification_flag_l1
);
943 if (shdr
->ref_pic_list_modification_flag_l1
) {
944 res
= ParseRefPicListModification(shdr
->num_ref_idx_l1_active_minus1
,
945 shdr
->ref_list_l1_modifications
);
954 H264Parser::Result
H264Parser::ParseWeightingFactors(
955 int num_ref_idx_active_minus1
,
956 int chroma_array_type
,
957 int luma_log2_weight_denom
,
958 int chroma_log2_weight_denom
,
959 H264WeightingFactors
* w_facts
) {
961 int def_luma_weight
= 1 << luma_log2_weight_denom
;
962 int def_chroma_weight
= 1 << chroma_log2_weight_denom
;
964 for (int i
= 0; i
< num_ref_idx_active_minus1
+ 1; ++i
) {
965 READ_BOOL_OR_RETURN(&w_facts
->luma_weight_flag
);
966 if (w_facts
->luma_weight_flag
) {
967 READ_SE_OR_RETURN(&w_facts
->luma_weight
[i
]);
968 IN_RANGE_OR_RETURN(w_facts
->luma_weight
[i
], -128, 127);
970 READ_SE_OR_RETURN(&w_facts
->luma_offset
[i
]);
971 IN_RANGE_OR_RETURN(w_facts
->luma_offset
[i
], -128, 127);
973 w_facts
->luma_weight
[i
] = def_luma_weight
;
974 w_facts
->luma_offset
[i
] = 0;
977 if (chroma_array_type
!= 0) {
978 READ_BOOL_OR_RETURN(&w_facts
->chroma_weight_flag
);
979 if (w_facts
->chroma_weight_flag
) {
980 for (int j
= 0; j
< 2; ++j
) {
981 READ_SE_OR_RETURN(&w_facts
->chroma_weight
[i
][j
]);
982 IN_RANGE_OR_RETURN(w_facts
->chroma_weight
[i
][j
], -128, 127);
984 READ_SE_OR_RETURN(&w_facts
->chroma_offset
[i
][j
]);
985 IN_RANGE_OR_RETURN(w_facts
->chroma_offset
[i
][j
], -128, 127);
988 for (int j
= 0; j
< 2; ++j
) {
989 w_facts
->chroma_weight
[i
][j
] = def_chroma_weight
;
990 w_facts
->chroma_offset
[i
][j
] = 0;
999 H264Parser::Result
H264Parser::ParsePredWeightTable(const H264SPS
& sps
,
1000 H264SliceHeader
* shdr
) {
1001 READ_UE_OR_RETURN(&shdr
->luma_log2_weight_denom
);
1002 TRUE_OR_RETURN(shdr
->luma_log2_weight_denom
< 8);
1004 if (sps
.chroma_array_type
!= 0)
1005 READ_UE_OR_RETURN(&shdr
->chroma_log2_weight_denom
);
1006 TRUE_OR_RETURN(shdr
->chroma_log2_weight_denom
< 8);
1008 Result res
= ParseWeightingFactors(shdr
->num_ref_idx_l0_active_minus1
,
1009 sps
.chroma_array_type
,
1010 shdr
->luma_log2_weight_denom
,
1011 shdr
->chroma_log2_weight_denom
,
1012 &shdr
->pred_weight_table_l0
);
1016 if (shdr
->IsBSlice()) {
1017 res
= ParseWeightingFactors(shdr
->num_ref_idx_l1_active_minus1
,
1018 sps
.chroma_array_type
,
1019 shdr
->luma_log2_weight_denom
,
1020 shdr
->chroma_log2_weight_denom
,
1021 &shdr
->pred_weight_table_l1
);
1029 H264Parser::Result
H264Parser::ParseDecRefPicMarking(H264SliceHeader
* shdr
) {
1030 if (shdr
->idr_pic_flag
) {
1031 READ_BOOL_OR_RETURN(&shdr
->no_output_of_prior_pics_flag
);
1032 READ_BOOL_OR_RETURN(&shdr
->long_term_reference_flag
);
1034 READ_BOOL_OR_RETURN(&shdr
->adaptive_ref_pic_marking_mode_flag
);
1036 H264DecRefPicMarking
* marking
;
1037 if (shdr
->adaptive_ref_pic_marking_mode_flag
) {
1039 for (i
= 0; i
< arraysize(shdr
->ref_pic_marking
); ++i
) {
1040 marking
= &shdr
->ref_pic_marking
[i
];
1042 READ_UE_OR_RETURN(&marking
->memory_mgmnt_control_operation
);
1043 if (marking
->memory_mgmnt_control_operation
== 0)
1046 if (marking
->memory_mgmnt_control_operation
== 1 ||
1047 marking
->memory_mgmnt_control_operation
== 3)
1048 READ_UE_OR_RETURN(&marking
->difference_of_pic_nums_minus1
);
1050 if (marking
->memory_mgmnt_control_operation
== 2)
1051 READ_UE_OR_RETURN(&marking
->long_term_pic_num
);
1053 if (marking
->memory_mgmnt_control_operation
== 3 ||
1054 marking
->memory_mgmnt_control_operation
== 6)
1055 READ_UE_OR_RETURN(&marking
->long_term_frame_idx
);
1057 if (marking
->memory_mgmnt_control_operation
== 4)
1058 READ_UE_OR_RETURN(&marking
->max_long_term_frame_idx_plus1
);
1060 if (marking
->memory_mgmnt_control_operation
> 6)
1061 return kInvalidStream
;
1064 if (i
== arraysize(shdr
->ref_pic_marking
)) {
1065 DVLOG(1) << "Ran out of dec ref pic marking fields";
1066 return kUnsupportedStream
;
1074 H264Parser::Result
H264Parser::ParseSliceHeader(const H264NALU
& nalu
,
1075 H264SliceHeader
* shdr
) {
1081 memset(shdr
, 0, sizeof(*shdr
));
1083 shdr
->idr_pic_flag
= (nalu
.nal_unit_type
== 5);
1084 shdr
->nal_ref_idc
= nalu
.nal_ref_idc
;
1085 shdr
->nalu_data
= nalu
.data
;
1086 shdr
->nalu_size
= nalu
.size
;
1088 READ_UE_OR_RETURN(&shdr
->first_mb_in_slice
);
1089 READ_UE_OR_RETURN(&shdr
->slice_type
);
1090 TRUE_OR_RETURN(shdr
->slice_type
< 10);
1092 READ_UE_OR_RETURN(&shdr
->pic_parameter_set_id
);
1094 pps
= GetPPS(shdr
->pic_parameter_set_id
);
1095 TRUE_OR_RETURN(pps
);
1097 sps
= GetSPS(pps
->seq_parameter_set_id
);
1098 TRUE_OR_RETURN(sps
);
1100 if (sps
->separate_colour_plane_flag
) {
1101 DVLOG(1) << "Interlaced streams not supported";
1102 return kUnsupportedStream
;
1105 READ_BITS_OR_RETURN(sps
->log2_max_frame_num_minus4
+ 4, &shdr
->frame_num
);
1106 if (!sps
->frame_mbs_only_flag
) {
1107 READ_BOOL_OR_RETURN(&shdr
->field_pic_flag
);
1108 if (shdr
->field_pic_flag
) {
1109 DVLOG(1) << "Interlaced streams not supported";
1110 return kUnsupportedStream
;
1114 if (shdr
->idr_pic_flag
)
1115 READ_UE_OR_RETURN(&shdr
->idr_pic_id
);
1117 if (sps
->pic_order_cnt_type
== 0) {
1118 READ_BITS_OR_RETURN(sps
->log2_max_pic_order_cnt_lsb_minus4
+ 4,
1119 &shdr
->pic_order_cnt_lsb
);
1120 if (pps
->bottom_field_pic_order_in_frame_present_flag
&&
1121 !shdr
->field_pic_flag
)
1122 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt_bottom
);
1125 if (sps
->pic_order_cnt_type
== 1 && !sps
->delta_pic_order_always_zero_flag
) {
1126 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt
[0]);
1127 if (pps
->bottom_field_pic_order_in_frame_present_flag
&&
1128 !shdr
->field_pic_flag
)
1129 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt
[1]);
1132 if (pps
->redundant_pic_cnt_present_flag
) {
1133 READ_UE_OR_RETURN(&shdr
->redundant_pic_cnt
);
1134 TRUE_OR_RETURN(shdr
->redundant_pic_cnt
< 128);
1137 if (shdr
->IsBSlice())
1138 READ_BOOL_OR_RETURN(&shdr
->direct_spatial_mv_pred_flag
);
1140 if (shdr
->IsPSlice() || shdr
->IsSPSlice() || shdr
->IsBSlice()) {
1141 READ_BOOL_OR_RETURN(&shdr
->num_ref_idx_active_override_flag
);
1142 if (shdr
->num_ref_idx_active_override_flag
) {
1143 READ_UE_OR_RETURN(&shdr
->num_ref_idx_l0_active_minus1
);
1144 if (shdr
->IsBSlice())
1145 READ_UE_OR_RETURN(&shdr
->num_ref_idx_l1_active_minus1
);
1147 shdr
->num_ref_idx_l0_active_minus1
=
1148 pps
->num_ref_idx_l0_default_active_minus1
;
1149 if (shdr
->IsBSlice()) {
1150 shdr
->num_ref_idx_l1_active_minus1
=
1151 pps
->num_ref_idx_l1_default_active_minus1
;
1155 if (shdr
->field_pic_flag
) {
1156 TRUE_OR_RETURN(shdr
->num_ref_idx_l0_active_minus1
< 32);
1157 TRUE_OR_RETURN(shdr
->num_ref_idx_l1_active_minus1
< 32);
1159 TRUE_OR_RETURN(shdr
->num_ref_idx_l0_active_minus1
< 16);
1160 TRUE_OR_RETURN(shdr
->num_ref_idx_l1_active_minus1
< 16);
1163 if (nalu
.nal_unit_type
== H264NALU::kCodedSliceExtension
) {
1164 return kUnsupportedStream
;
1166 res
= ParseRefPicListModifications(shdr
);
1171 if ((pps
->weighted_pred_flag
&& (shdr
->IsPSlice() || shdr
->IsSPSlice())) ||
1172 (pps
->weighted_bipred_idc
== 1 && shdr
->IsBSlice())) {
1173 res
= ParsePredWeightTable(*sps
, shdr
);
1178 if (nalu
.nal_ref_idc
!= 0) {
1179 res
= ParseDecRefPicMarking(shdr
);
1184 if (pps
->entropy_coding_mode_flag
&& !shdr
->IsISlice() &&
1185 !shdr
->IsSISlice()) {
1186 READ_UE_OR_RETURN(&shdr
->cabac_init_idc
);
1187 TRUE_OR_RETURN(shdr
->cabac_init_idc
< 3);
1190 READ_SE_OR_RETURN(&shdr
->slice_qp_delta
);
1192 if (shdr
->IsSPSlice() || shdr
->IsSISlice()) {
1193 if (shdr
->IsSPSlice())
1194 READ_BOOL_OR_RETURN(&shdr
->sp_for_switch_flag
);
1195 READ_SE_OR_RETURN(&shdr
->slice_qs_delta
);
1198 if (pps
->deblocking_filter_control_present_flag
) {
1199 READ_UE_OR_RETURN(&shdr
->disable_deblocking_filter_idc
);
1200 TRUE_OR_RETURN(shdr
->disable_deblocking_filter_idc
< 3);
1202 if (shdr
->disable_deblocking_filter_idc
!= 1) {
1203 READ_SE_OR_RETURN(&shdr
->slice_alpha_c0_offset_div2
);
1204 IN_RANGE_OR_RETURN(shdr
->slice_alpha_c0_offset_div2
, -6, 6);
1206 READ_SE_OR_RETURN(&shdr
->slice_beta_offset_div2
);
1207 IN_RANGE_OR_RETURN(shdr
->slice_beta_offset_div2
, -6, 6);
1211 if (pps
->num_slice_groups_minus1
> 0) {
1212 DVLOG(1) << "Slice groups not supported";
1213 return kUnsupportedStream
;
1216 size_t epb
= br_
.NumEmulationPreventionBytesRead();
1217 shdr
->header_bit_size
= (shdr
->nalu_size
- epb
) * 8 - br_
.NumBitsLeft();
1222 H264Parser::Result
H264Parser::ParseSEI(H264SEIMessage
* sei_msg
) {
1225 memset(sei_msg
, 0, sizeof(*sei_msg
));
1227 READ_BITS_OR_RETURN(8, &byte
);
1228 while (byte
== 0xff) {
1229 sei_msg
->type
+= 255;
1230 READ_BITS_OR_RETURN(8, &byte
);
1232 sei_msg
->type
+= byte
;
1234 READ_BITS_OR_RETURN(8, &byte
);
1235 while (byte
== 0xff) {
1236 sei_msg
->payload_size
+= 255;
1237 READ_BITS_OR_RETURN(8, &byte
);
1239 sei_msg
->payload_size
+= byte
;
1241 DVLOG(4) << "Found SEI message type: " << sei_msg
->type
1242 << " payload size: " << sei_msg
->payload_size
;
1244 switch (sei_msg
->type
) {
1245 case H264SEIMessage::kSEIRecoveryPoint
:
1246 READ_UE_OR_RETURN(&sei_msg
->recovery_point
.recovery_frame_cnt
);
1247 READ_BOOL_OR_RETURN(&sei_msg
->recovery_point
.exact_match_flag
);
1248 READ_BOOL_OR_RETURN(&sei_msg
->recovery_point
.broken_link_flag
);
1249 READ_BITS_OR_RETURN(2, &sei_msg
->recovery_point
.changing_slice_group_idc
);
1253 DVLOG(4) << "Unsupported SEI message";
1260 } // namespace media