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; \
109 enum AspectRatioIdc
{
114 // VUI parameters: Table E-1 "Meaning of sample aspect ratio indicator"
115 static const int kTableSarWidth
[] = {
116 0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
118 static const int kTableSarHeight
[] = {
119 0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
121 COMPILE_ASSERT(arraysize(kTableSarWidth
) == arraysize(kTableSarHeight
),
122 sar_tables_must_have_same_size
);
124 H264Parser::H264Parser() {
128 H264Parser::~H264Parser() {
129 STLDeleteValues(&active_SPSes_
);
130 STLDeleteValues(&active_PPSes_
);
133 void H264Parser::Reset() {
138 void H264Parser::SetStream(const uint8
* stream
, off_t stream_size
) {
140 DCHECK_GT(stream_size
, 0);
143 bytes_left_
= stream_size
;
146 const H264PPS
* H264Parser::GetPPS(int pps_id
) {
147 return active_PPSes_
[pps_id
];
150 const H264SPS
* H264Parser::GetSPS(int sps_id
) {
151 return active_SPSes_
[sps_id
];
154 static inline bool IsStartCode(const uint8
* data
) {
155 return data
[0] == 0x00 && data
[1] == 0x00 && data
[2] == 0x01;
159 bool H264Parser::FindStartCode(const uint8
* data
, off_t data_size
,
160 off_t
* offset
, off_t
* start_code_size
) {
161 DCHECK_GE(data_size
, 0);
162 off_t bytes_left
= data_size
;
164 while (bytes_left
>= 3) {
165 if (IsStartCode(data
)) {
166 // Found three-byte start code, set pointer at its beginning.
167 *offset
= data_size
- bytes_left
;
168 *start_code_size
= 3;
170 // If there is a zero byte before this start code,
171 // then it's actually a four-byte start code, so backtrack one byte.
172 if (*offset
> 0 && *(data
- 1) == 0x00) {
174 ++(*start_code_size
);
184 // End of data: offset is pointing to the first byte that was not considered
185 // as a possible start of a start code.
186 // Note: there is no security issue when receiving a negative |data_size|
187 // since in this case, |bytes_left| is equal to |data_size| and thus
188 // |*offset| is equal to 0 (valid offset).
189 *offset
= data_size
- bytes_left
;
190 *start_code_size
= 0;
194 bool H264Parser::LocateNALU(off_t
* nalu_size
, off_t
* start_code_size
) {
195 // Find the start code of next NALU.
196 off_t nalu_start_off
= 0;
197 off_t annexb_start_code_size
= 0;
198 if (!FindStartCode(stream_
, bytes_left_
,
199 &nalu_start_off
, &annexb_start_code_size
)) {
200 DVLOG(4) << "Could not find start code, end of stream?";
204 // Move the stream to the beginning of the NALU (pointing at the start code).
205 stream_
+= nalu_start_off
;
206 bytes_left_
-= nalu_start_off
;
208 const uint8
* nalu_data
= stream_
+ annexb_start_code_size
;
209 off_t max_nalu_data_size
= bytes_left_
- annexb_start_code_size
;
210 if (max_nalu_data_size
<= 0) {
211 DVLOG(3) << "End of stream";
215 // Find the start code of next NALU;
216 // if successful, |nalu_size_without_start_code| is the number of bytes from
217 // after previous start code to before this one;
218 // if next start code is not found, it is still a valid NALU since there
219 // are some bytes left after the first start code: all the remaining bytes
220 // belong to the current NALU.
221 off_t next_start_code_size
= 0;
222 off_t nalu_size_without_start_code
= 0;
223 if (!FindStartCode(nalu_data
, max_nalu_data_size
,
224 &nalu_size_without_start_code
, &next_start_code_size
)) {
225 nalu_size_without_start_code
= max_nalu_data_size
;
227 *nalu_size
= nalu_size_without_start_code
+ annexb_start_code_size
;
228 *start_code_size
= annexb_start_code_size
;
232 H264Parser::Result
H264Parser::ReadUE(int* val
) {
237 // Count the number of contiguous zero bits.
239 READ_BITS_OR_RETURN(1, &bit
);
244 return kInvalidStream
;
246 // Calculate exp-Golomb code value of size num_bits.
247 *val
= (1 << num_bits
) - 1;
250 READ_BITS_OR_RETURN(num_bits
, &rest
);
257 H264Parser::Result
H264Parser::ReadSE(int* val
) {
261 // See Chapter 9 in the spec.
274 H264Parser::Result
H264Parser::AdvanceToNextNALU(H264NALU
* nalu
) {
275 off_t start_code_size
;
276 off_t nalu_size_with_start_code
;
277 if (!LocateNALU(&nalu_size_with_start_code
, &start_code_size
)) {
278 DVLOG(4) << "Could not find next NALU, bytes left in stream: "
283 nalu
->data
= stream_
+ start_code_size
;
284 nalu
->size
= nalu_size_with_start_code
- start_code_size
;
285 DVLOG(4) << "NALU found: size=" << nalu_size_with_start_code
;
287 // Initialize bit reader at the start of found NALU.
288 if (!br_
.Initialize(nalu
->data
, nalu
->size
))
291 // Move parser state to after this NALU, so next time AdvanceToNextNALU
292 // is called, we will effectively be skipping it;
293 // other parsing functions will use the position saved
294 // in bit reader for parsing, so we don't have to remember it here.
295 stream_
+= nalu_size_with_start_code
;
296 bytes_left_
-= nalu_size_with_start_code
;
298 // Read NALU header, skip the forbidden_zero_bit, but check for it.
300 READ_BITS_OR_RETURN(1, &data
);
301 TRUE_OR_RETURN(data
== 0);
303 READ_BITS_OR_RETURN(2, &nalu
->nal_ref_idc
);
304 READ_BITS_OR_RETURN(5, &nalu
->nal_unit_type
);
306 DVLOG(4) << "NALU type: " << static_cast<int>(nalu
->nal_unit_type
)
307 << " at: " << reinterpret_cast<const void*>(nalu
->data
)
308 << " size: " << nalu
->size
309 << " ref: " << static_cast<int>(nalu
->nal_ref_idc
);
314 // Default scaling lists (per spec).
315 static const int kDefault4x4Intra
[kH264ScalingList4x4Length
] = {
316 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
318 static const int kDefault4x4Inter
[kH264ScalingList4x4Length
] = {
319 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
321 static const int kDefault8x8Intra
[kH264ScalingList8x8Length
] = {
322 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
323 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
324 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
325 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
327 static const int kDefault8x8Inter
[kH264ScalingList8x8Length
] = {
328 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
329 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
330 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
331 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
333 static inline void DefaultScalingList4x4(
335 int scaling_list4x4
[][kH264ScalingList4x4Length
]) {
339 memcpy(scaling_list4x4
[i
], kDefault4x4Intra
, sizeof(kDefault4x4Intra
));
341 memcpy(scaling_list4x4
[i
], kDefault4x4Inter
, sizeof(kDefault4x4Inter
));
344 static inline void DefaultScalingList8x8(
346 int scaling_list8x8
[][kH264ScalingList8x8Length
]) {
350 memcpy(scaling_list8x8
[i
], kDefault8x8Intra
, sizeof(kDefault8x8Intra
));
352 memcpy(scaling_list8x8
[i
], kDefault8x8Inter
, sizeof(kDefault8x8Inter
));
355 static void FallbackScalingList4x4(
357 const int default_scaling_list_intra
[],
358 const int default_scaling_list_inter
[],
359 int scaling_list4x4
[][kH264ScalingList4x4Length
]) {
360 static const int kScalingList4x4ByteSize
=
361 sizeof(scaling_list4x4
[0][0]) * kH264ScalingList4x4Length
;
365 memcpy(scaling_list4x4
[i
], default_scaling_list_intra
,
366 kScalingList4x4ByteSize
);
370 memcpy(scaling_list4x4
[i
], scaling_list4x4
[0], kScalingList4x4ByteSize
);
374 memcpy(scaling_list4x4
[i
], scaling_list4x4
[1], kScalingList4x4ByteSize
);
378 memcpy(scaling_list4x4
[i
], default_scaling_list_inter
,
379 kScalingList4x4ByteSize
);
383 memcpy(scaling_list4x4
[i
], scaling_list4x4
[3], kScalingList4x4ByteSize
);
387 memcpy(scaling_list4x4
[i
], scaling_list4x4
[4], kScalingList4x4ByteSize
);
396 static void FallbackScalingList8x8(
398 const int default_scaling_list_intra
[],
399 const int default_scaling_list_inter
[],
400 int scaling_list8x8
[][kH264ScalingList8x8Length
]) {
401 static const int kScalingList8x8ByteSize
=
402 sizeof(scaling_list8x8
[0][0]) * kH264ScalingList8x8Length
;
406 memcpy(scaling_list8x8
[i
], default_scaling_list_intra
,
407 kScalingList8x8ByteSize
);
411 memcpy(scaling_list8x8
[i
], default_scaling_list_inter
,
412 kScalingList8x8ByteSize
);
416 memcpy(scaling_list8x8
[i
], scaling_list8x8
[0], kScalingList8x8ByteSize
);
420 memcpy(scaling_list8x8
[i
], scaling_list8x8
[1], kScalingList8x8ByteSize
);
424 memcpy(scaling_list8x8
[i
], scaling_list8x8
[2], kScalingList8x8ByteSize
);
428 memcpy(scaling_list8x8
[i
], scaling_list8x8
[3], kScalingList8x8ByteSize
);
437 H264Parser::Result
H264Parser::ParseScalingList(int size
,
440 // See chapter 7.3.2.1.1.1.
445 *use_default
= false;
447 for (int j
= 0; j
< size
; ++j
) {
448 if (next_scale
!= 0) {
449 READ_SE_OR_RETURN(&delta_scale
);
450 IN_RANGE_OR_RETURN(delta_scale
, -128, 127);
451 next_scale
= (last_scale
+ delta_scale
+ 256) & 0xff;
453 if (j
== 0 && next_scale
== 0) {
459 scaling_list
[j
] = (next_scale
== 0) ? last_scale
: next_scale
;
460 last_scale
= scaling_list
[j
];
466 H264Parser::Result
H264Parser::ParseSPSScalingLists(H264SPS
* sps
) {
468 bool seq_scaling_list_present_flag
;
472 // Parse scaling_list4x4.
473 for (int i
= 0; i
< 6; ++i
) {
474 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag
);
476 if (seq_scaling_list_present_flag
) {
477 res
= ParseScalingList(arraysize(sps
->scaling_list4x4
[i
]),
478 sps
->scaling_list4x4
[i
],
484 DefaultScalingList4x4(i
, sps
->scaling_list4x4
);
487 FallbackScalingList4x4(
488 i
, kDefault4x4Intra
, kDefault4x4Inter
, sps
->scaling_list4x4
);
492 // Parse scaling_list8x8.
493 for (int i
= 0; i
< ((sps
->chroma_format_idc
!= 3) ? 2 : 6); ++i
) {
494 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag
);
496 if (seq_scaling_list_present_flag
) {
497 res
= ParseScalingList(arraysize(sps
->scaling_list8x8
[i
]),
498 sps
->scaling_list8x8
[i
],
504 DefaultScalingList8x8(i
, sps
->scaling_list8x8
);
507 FallbackScalingList8x8(
508 i
, kDefault8x8Intra
, kDefault8x8Inter
, sps
->scaling_list8x8
);
515 H264Parser::Result
H264Parser::ParsePPSScalingLists(const H264SPS
& sps
,
518 bool pic_scaling_list_present_flag
;
522 for (int i
= 0; i
< 6; ++i
) {
523 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag
);
525 if (pic_scaling_list_present_flag
) {
526 res
= ParseScalingList(arraysize(pps
->scaling_list4x4
[i
]),
527 pps
->scaling_list4x4
[i
],
533 DefaultScalingList4x4(i
, pps
->scaling_list4x4
);
536 if (sps
.seq_scaling_matrix_present_flag
) {
537 // Table 7-2 fallback rule A in spec.
538 FallbackScalingList4x4(
539 i
, kDefault4x4Intra
, kDefault4x4Inter
, pps
->scaling_list4x4
);
541 // Table 7-2 fallback rule B in spec.
542 FallbackScalingList4x4(i
,
543 sps
.scaling_list4x4
[0],
544 sps
.scaling_list4x4
[3],
545 pps
->scaling_list4x4
);
550 if (pps
->transform_8x8_mode_flag
) {
551 for (int i
= 0; i
< ((sps
.chroma_format_idc
!= 3) ? 2 : 6); ++i
) {
552 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag
);
554 if (pic_scaling_list_present_flag
) {
555 res
= ParseScalingList(arraysize(pps
->scaling_list8x8
[i
]),
556 pps
->scaling_list8x8
[i
],
562 DefaultScalingList8x8(i
, pps
->scaling_list8x8
);
565 if (sps
.seq_scaling_matrix_present_flag
) {
566 // Table 7-2 fallback rule A in spec.
567 FallbackScalingList8x8(
568 i
, kDefault8x8Intra
, kDefault8x8Inter
, pps
->scaling_list8x8
);
570 // Table 7-2 fallback rule B in spec.
571 FallbackScalingList8x8(i
,
572 sps
.scaling_list8x8
[0],
573 sps
.scaling_list8x8
[1],
574 pps
->scaling_list8x8
);
582 H264Parser::Result
H264Parser::ParseAndIgnoreHRDParameters(
583 bool* hrd_parameters_present
) {
585 READ_BOOL_OR_RETURN(&data
); // {nal,vcl}_hrd_parameters_present_flag
589 *hrd_parameters_present
= true;
592 READ_UE_OR_RETURN(&cpb_cnt_minus1
);
593 IN_RANGE_OR_RETURN(cpb_cnt_minus1
, 0, 31);
594 READ_BITS_OR_RETURN(8, &data
); // bit_rate_scale, cpb_size_scale
595 for (int i
= 0; i
<= cpb_cnt_minus1
; ++i
) {
596 READ_UE_OR_RETURN(&data
); // bit_rate_value_minus1[i]
597 READ_UE_OR_RETURN(&data
); // cpb_size_value_minus1[i]
598 READ_BOOL_OR_RETURN(&data
); // cbr_flag
600 READ_BITS_OR_RETURN(20, &data
); // cpb/dpb delays, etc.
605 H264Parser::Result
H264Parser::ParseVUIParameters(H264SPS
* sps
) {
606 bool aspect_ratio_info_present_flag
;
607 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag
);
608 if (aspect_ratio_info_present_flag
) {
609 int aspect_ratio_idc
;
610 READ_BITS_OR_RETURN(8, &aspect_ratio_idc
);
611 if (aspect_ratio_idc
== kExtendedSar
) {
612 READ_BITS_OR_RETURN(16, &sps
->sar_width
);
613 READ_BITS_OR_RETURN(16, &sps
->sar_height
);
615 const int max_aspect_ratio_idc
= arraysize(kTableSarWidth
) - 1;
616 IN_RANGE_OR_RETURN(aspect_ratio_idc
, 0, max_aspect_ratio_idc
);
617 sps
->sar_width
= kTableSarWidth
[aspect_ratio_idc
];
618 sps
->sar_height
= kTableSarHeight
[aspect_ratio_idc
];
623 // Read and ignore overscan and video signal type info.
624 READ_BOOL_OR_RETURN(&data
); // overscan_info_present_flag
626 READ_BOOL_OR_RETURN(&data
); // overscan_appropriate_flag
628 READ_BOOL_OR_RETURN(&data
); // video_signal_type_present_flag
630 READ_BITS_OR_RETURN(3, &data
); // video_format
631 READ_BOOL_OR_RETURN(&data
); // video_full_range_flag
632 READ_BOOL_OR_RETURN(&data
); // colour_description_present_flag
634 READ_BITS_OR_RETURN(24, &data
); // color description syntax elements
637 READ_BOOL_OR_RETURN(&data
); // chroma_loc_info_present_flag
639 READ_UE_OR_RETURN(&data
); // chroma_sample_loc_type_top_field
640 READ_UE_OR_RETURN(&data
); // chroma_sample_loc_type_bottom_field
643 // Read and ignore timing info.
644 READ_BOOL_OR_RETURN(&data
); // timing_info_present_flag
646 READ_BITS_OR_RETURN(16, &data
); // num_units_in_tick
647 READ_BITS_OR_RETURN(16, &data
); // num_units_in_tick
648 READ_BITS_OR_RETURN(16, &data
); // time_scale
649 READ_BITS_OR_RETURN(16, &data
); // time_scale
650 READ_BOOL_OR_RETURN(&data
); // fixed_frame_rate_flag
653 // Read and ignore NAL HRD parameters, if present.
654 bool hrd_parameters_present
= false;
655 Result res
= ParseAndIgnoreHRDParameters(&hrd_parameters_present
);
659 // Read and ignore VCL HRD parameters, if present.
660 res
= ParseAndIgnoreHRDParameters(&hrd_parameters_present
);
664 if (hrd_parameters_present
) // One of NAL or VCL params present is enough.
665 READ_BOOL_OR_RETURN(&data
); // low_delay_hrd_flag
667 READ_BOOL_OR_RETURN(&data
); // pic_struct_present_flag
668 READ_BOOL_OR_RETURN(&sps
->bitstream_restriction_flag
);
669 if (sps
->bitstream_restriction_flag
) {
670 READ_BOOL_OR_RETURN(&data
); // motion_vectors_over_pic_boundaries_flag
671 READ_UE_OR_RETURN(&data
); // max_bytes_per_pic_denom
672 READ_UE_OR_RETURN(&data
); // max_bits_per_mb_denom
673 READ_UE_OR_RETURN(&data
); // log2_max_mv_length_horizontal
674 READ_UE_OR_RETURN(&data
); // log2_max_mv_length_vertical
675 READ_UE_OR_RETURN(&sps
->max_num_reorder_frames
);
676 READ_UE_OR_RETURN(&sps
->max_dec_frame_buffering
);
677 TRUE_OR_RETURN(sps
->max_dec_frame_buffering
>= sps
->max_num_ref_frames
);
679 sps
->max_num_reorder_frames
, 0, sps
->max_dec_frame_buffering
);
685 static void FillDefaultSeqScalingLists(H264SPS
* sps
) {
686 for (int i
= 0; i
< 6; ++i
)
687 for (int j
= 0; j
< kH264ScalingList4x4Length
; ++j
)
688 sps
->scaling_list4x4
[i
][j
] = 16;
690 for (int i
= 0; i
< 6; ++i
)
691 for (int j
= 0; j
< kH264ScalingList8x8Length
; ++j
)
692 sps
->scaling_list8x8
[i
][j
] = 16;
695 H264Parser::Result
H264Parser::ParseSPS(int* sps_id
) {
702 scoped_ptr
<H264SPS
> sps(new H264SPS());
704 READ_BITS_OR_RETURN(8, &sps
->profile_idc
);
705 READ_BOOL_OR_RETURN(&sps
->constraint_set0_flag
);
706 READ_BOOL_OR_RETURN(&sps
->constraint_set1_flag
);
707 READ_BOOL_OR_RETURN(&sps
->constraint_set2_flag
);
708 READ_BOOL_OR_RETURN(&sps
->constraint_set3_flag
);
709 READ_BOOL_OR_RETURN(&sps
->constraint_set4_flag
);
710 READ_BOOL_OR_RETURN(&sps
->constraint_set5_flag
);
711 READ_BITS_OR_RETURN(2, &data
); // reserved_zero_2bits
712 READ_BITS_OR_RETURN(8, &sps
->level_idc
);
713 READ_UE_OR_RETURN(&sps
->seq_parameter_set_id
);
714 TRUE_OR_RETURN(sps
->seq_parameter_set_id
< 32);
716 if (sps
->profile_idc
== 100 || sps
->profile_idc
== 110 ||
717 sps
->profile_idc
== 122 || sps
->profile_idc
== 244 ||
718 sps
->profile_idc
== 44 || sps
->profile_idc
== 83 ||
719 sps
->profile_idc
== 86 || sps
->profile_idc
== 118 ||
720 sps
->profile_idc
== 128) {
721 READ_UE_OR_RETURN(&sps
->chroma_format_idc
);
722 TRUE_OR_RETURN(sps
->chroma_format_idc
< 4);
724 if (sps
->chroma_format_idc
== 3)
725 READ_BOOL_OR_RETURN(&sps
->separate_colour_plane_flag
);
727 READ_UE_OR_RETURN(&sps
->bit_depth_luma_minus8
);
728 TRUE_OR_RETURN(sps
->bit_depth_luma_minus8
< 7);
730 READ_UE_OR_RETURN(&sps
->bit_depth_chroma_minus8
);
731 TRUE_OR_RETURN(sps
->bit_depth_chroma_minus8
< 7);
733 READ_BOOL_OR_RETURN(&sps
->qpprime_y_zero_transform_bypass_flag
);
734 READ_BOOL_OR_RETURN(&sps
->seq_scaling_matrix_present_flag
);
736 if (sps
->seq_scaling_matrix_present_flag
) {
737 DVLOG(4) << "Scaling matrix present";
738 res
= ParseSPSScalingLists(sps
.get());
742 FillDefaultSeqScalingLists(sps
.get());
745 sps
->chroma_format_idc
= 1;
746 FillDefaultSeqScalingLists(sps
.get());
749 if (sps
->separate_colour_plane_flag
)
750 sps
->chroma_array_type
= 0;
752 sps
->chroma_array_type
= sps
->chroma_format_idc
;
754 READ_UE_OR_RETURN(&sps
->log2_max_frame_num_minus4
);
755 TRUE_OR_RETURN(sps
->log2_max_frame_num_minus4
< 13);
757 READ_UE_OR_RETURN(&sps
->pic_order_cnt_type
);
758 TRUE_OR_RETURN(sps
->pic_order_cnt_type
< 3);
760 sps
->expected_delta_per_pic_order_cnt_cycle
= 0;
761 if (sps
->pic_order_cnt_type
== 0) {
762 READ_UE_OR_RETURN(&sps
->log2_max_pic_order_cnt_lsb_minus4
);
763 TRUE_OR_RETURN(sps
->log2_max_pic_order_cnt_lsb_minus4
< 13);
764 } else if (sps
->pic_order_cnt_type
== 1) {
765 READ_BOOL_OR_RETURN(&sps
->delta_pic_order_always_zero_flag
);
766 READ_SE_OR_RETURN(&sps
->offset_for_non_ref_pic
);
767 READ_SE_OR_RETURN(&sps
->offset_for_top_to_bottom_field
);
768 READ_UE_OR_RETURN(&sps
->num_ref_frames_in_pic_order_cnt_cycle
);
769 TRUE_OR_RETURN(sps
->num_ref_frames_in_pic_order_cnt_cycle
< 255);
771 for (int i
= 0; i
< sps
->num_ref_frames_in_pic_order_cnt_cycle
; ++i
) {
772 READ_SE_OR_RETURN(&sps
->offset_for_ref_frame
[i
]);
773 sps
->expected_delta_per_pic_order_cnt_cycle
+=
774 sps
->offset_for_ref_frame
[i
];
778 READ_UE_OR_RETURN(&sps
->max_num_ref_frames
);
779 READ_BOOL_OR_RETURN(&sps
->gaps_in_frame_num_value_allowed_flag
);
781 if (sps
->gaps_in_frame_num_value_allowed_flag
)
782 return kUnsupportedStream
;
784 READ_UE_OR_RETURN(&sps
->pic_width_in_mbs_minus1
);
785 READ_UE_OR_RETURN(&sps
->pic_height_in_map_units_minus1
);
787 READ_BOOL_OR_RETURN(&sps
->frame_mbs_only_flag
);
788 if (!sps
->frame_mbs_only_flag
)
789 READ_BOOL_OR_RETURN(&sps
->mb_adaptive_frame_field_flag
);
791 READ_BOOL_OR_RETURN(&sps
->direct_8x8_inference_flag
);
793 READ_BOOL_OR_RETURN(&sps
->frame_cropping_flag
);
794 if (sps
->frame_cropping_flag
) {
795 READ_UE_OR_RETURN(&sps
->frame_crop_left_offset
);
796 READ_UE_OR_RETURN(&sps
->frame_crop_right_offset
);
797 READ_UE_OR_RETURN(&sps
->frame_crop_top_offset
);
798 READ_UE_OR_RETURN(&sps
->frame_crop_bottom_offset
);
801 READ_BOOL_OR_RETURN(&sps
->vui_parameters_present_flag
);
802 if (sps
->vui_parameters_present_flag
) {
803 DVLOG(4) << "VUI parameters present";
804 res
= ParseVUIParameters(sps
.get());
809 // If an SPS with the same id already exists, replace it.
810 *sps_id
= sps
->seq_parameter_set_id
;
811 delete active_SPSes_
[*sps_id
];
812 active_SPSes_
[*sps_id
] = sps
.release();
817 H264Parser::Result
H264Parser::ParsePPS(int* pps_id
) {
824 scoped_ptr
<H264PPS
> pps(new H264PPS());
826 READ_UE_OR_RETURN(&pps
->pic_parameter_set_id
);
827 READ_UE_OR_RETURN(&pps
->seq_parameter_set_id
);
828 TRUE_OR_RETURN(pps
->seq_parameter_set_id
< 32);
830 sps
= GetSPS(pps
->seq_parameter_set_id
);
833 READ_BOOL_OR_RETURN(&pps
->entropy_coding_mode_flag
);
834 READ_BOOL_OR_RETURN(&pps
->bottom_field_pic_order_in_frame_present_flag
);
836 READ_UE_OR_RETURN(&pps
->num_slice_groups_minus1
);
837 if (pps
->num_slice_groups_minus1
> 1) {
838 DVLOG(1) << "Slice groups not supported";
839 return kUnsupportedStream
;
842 READ_UE_OR_RETURN(&pps
->num_ref_idx_l0_default_active_minus1
);
843 TRUE_OR_RETURN(pps
->num_ref_idx_l0_default_active_minus1
< 32);
845 READ_UE_OR_RETURN(&pps
->num_ref_idx_l1_default_active_minus1
);
846 TRUE_OR_RETURN(pps
->num_ref_idx_l1_default_active_minus1
< 32);
848 READ_BOOL_OR_RETURN(&pps
->weighted_pred_flag
);
849 READ_BITS_OR_RETURN(2, &pps
->weighted_bipred_idc
);
850 TRUE_OR_RETURN(pps
->weighted_bipred_idc
< 3);
852 READ_SE_OR_RETURN(&pps
->pic_init_qp_minus26
);
853 IN_RANGE_OR_RETURN(pps
->pic_init_qp_minus26
, -26, 25);
855 READ_SE_OR_RETURN(&pps
->pic_init_qs_minus26
);
856 IN_RANGE_OR_RETURN(pps
->pic_init_qs_minus26
, -26, 25);
858 READ_SE_OR_RETURN(&pps
->chroma_qp_index_offset
);
859 IN_RANGE_OR_RETURN(pps
->chroma_qp_index_offset
, -12, 12);
860 pps
->second_chroma_qp_index_offset
= pps
->chroma_qp_index_offset
;
862 READ_BOOL_OR_RETURN(&pps
->deblocking_filter_control_present_flag
);
863 READ_BOOL_OR_RETURN(&pps
->constrained_intra_pred_flag
);
864 READ_BOOL_OR_RETURN(&pps
->redundant_pic_cnt_present_flag
);
866 if (br_
.HasMoreRBSPData()) {
867 READ_BOOL_OR_RETURN(&pps
->transform_8x8_mode_flag
);
868 READ_BOOL_OR_RETURN(&pps
->pic_scaling_matrix_present_flag
);
870 if (pps
->pic_scaling_matrix_present_flag
) {
871 DVLOG(4) << "Picture scaling matrix present";
872 res
= ParsePPSScalingLists(*sps
, pps
.get());
877 READ_SE_OR_RETURN(&pps
->second_chroma_qp_index_offset
);
880 // If a PPS with the same id already exists, replace it.
881 *pps_id
= pps
->pic_parameter_set_id
;
882 delete active_PPSes_
[*pps_id
];
883 active_PPSes_
[*pps_id
] = pps
.release();
888 H264Parser::Result
H264Parser::ParseRefPicListModification(
889 int num_ref_idx_active_minus1
,
890 H264ModificationOfPicNum
* ref_list_mods
) {
891 H264ModificationOfPicNum
* pic_num_mod
;
893 if (num_ref_idx_active_minus1
>= 32)
894 return kInvalidStream
;
896 for (int i
= 0; i
< 32; ++i
) {
897 pic_num_mod
= &ref_list_mods
[i
];
898 READ_UE_OR_RETURN(&pic_num_mod
->modification_of_pic_nums_idc
);
899 TRUE_OR_RETURN(pic_num_mod
->modification_of_pic_nums_idc
< 4);
901 switch (pic_num_mod
->modification_of_pic_nums_idc
) {
904 READ_UE_OR_RETURN(&pic_num_mod
->abs_diff_pic_num_minus1
);
908 READ_UE_OR_RETURN(&pic_num_mod
->long_term_pic_num
);
912 // Per spec, list cannot be empty.
914 return kInvalidStream
;
918 return kInvalidStream
;
922 // If we got here, we didn't get loop end marker prematurely,
923 // so make sure it is there for our client.
924 int modification_of_pic_nums_idc
;
925 READ_UE_OR_RETURN(&modification_of_pic_nums_idc
);
926 TRUE_OR_RETURN(modification_of_pic_nums_idc
== 3);
931 H264Parser::Result
H264Parser::ParseRefPicListModifications(
932 H264SliceHeader
* shdr
) {
935 if (!shdr
->IsISlice() && !shdr
->IsSISlice()) {
936 READ_BOOL_OR_RETURN(&shdr
->ref_pic_list_modification_flag_l0
);
937 if (shdr
->ref_pic_list_modification_flag_l0
) {
938 res
= ParseRefPicListModification(shdr
->num_ref_idx_l0_active_minus1
,
939 shdr
->ref_list_l0_modifications
);
945 if (shdr
->IsBSlice()) {
946 READ_BOOL_OR_RETURN(&shdr
->ref_pic_list_modification_flag_l1
);
947 if (shdr
->ref_pic_list_modification_flag_l1
) {
948 res
= ParseRefPicListModification(shdr
->num_ref_idx_l1_active_minus1
,
949 shdr
->ref_list_l1_modifications
);
958 H264Parser::Result
H264Parser::ParseWeightingFactors(
959 int num_ref_idx_active_minus1
,
960 int chroma_array_type
,
961 int luma_log2_weight_denom
,
962 int chroma_log2_weight_denom
,
963 H264WeightingFactors
* w_facts
) {
965 int def_luma_weight
= 1 << luma_log2_weight_denom
;
966 int def_chroma_weight
= 1 << chroma_log2_weight_denom
;
968 for (int i
= 0; i
< num_ref_idx_active_minus1
+ 1; ++i
) {
969 READ_BOOL_OR_RETURN(&w_facts
->luma_weight_flag
);
970 if (w_facts
->luma_weight_flag
) {
971 READ_SE_OR_RETURN(&w_facts
->luma_weight
[i
]);
972 IN_RANGE_OR_RETURN(w_facts
->luma_weight
[i
], -128, 127);
974 READ_SE_OR_RETURN(&w_facts
->luma_offset
[i
]);
975 IN_RANGE_OR_RETURN(w_facts
->luma_offset
[i
], -128, 127);
977 w_facts
->luma_weight
[i
] = def_luma_weight
;
978 w_facts
->luma_offset
[i
] = 0;
981 if (chroma_array_type
!= 0) {
982 READ_BOOL_OR_RETURN(&w_facts
->chroma_weight_flag
);
983 if (w_facts
->chroma_weight_flag
) {
984 for (int j
= 0; j
< 2; ++j
) {
985 READ_SE_OR_RETURN(&w_facts
->chroma_weight
[i
][j
]);
986 IN_RANGE_OR_RETURN(w_facts
->chroma_weight
[i
][j
], -128, 127);
988 READ_SE_OR_RETURN(&w_facts
->chroma_offset
[i
][j
]);
989 IN_RANGE_OR_RETURN(w_facts
->chroma_offset
[i
][j
], -128, 127);
992 for (int j
= 0; j
< 2; ++j
) {
993 w_facts
->chroma_weight
[i
][j
] = def_chroma_weight
;
994 w_facts
->chroma_offset
[i
][j
] = 0;
1003 H264Parser::Result
H264Parser::ParsePredWeightTable(const H264SPS
& sps
,
1004 H264SliceHeader
* shdr
) {
1005 READ_UE_OR_RETURN(&shdr
->luma_log2_weight_denom
);
1006 TRUE_OR_RETURN(shdr
->luma_log2_weight_denom
< 8);
1008 if (sps
.chroma_array_type
!= 0)
1009 READ_UE_OR_RETURN(&shdr
->chroma_log2_weight_denom
);
1010 TRUE_OR_RETURN(shdr
->chroma_log2_weight_denom
< 8);
1012 Result res
= ParseWeightingFactors(shdr
->num_ref_idx_l0_active_minus1
,
1013 sps
.chroma_array_type
,
1014 shdr
->luma_log2_weight_denom
,
1015 shdr
->chroma_log2_weight_denom
,
1016 &shdr
->pred_weight_table_l0
);
1020 if (shdr
->IsBSlice()) {
1021 res
= ParseWeightingFactors(shdr
->num_ref_idx_l1_active_minus1
,
1022 sps
.chroma_array_type
,
1023 shdr
->luma_log2_weight_denom
,
1024 shdr
->chroma_log2_weight_denom
,
1025 &shdr
->pred_weight_table_l1
);
1033 H264Parser::Result
H264Parser::ParseDecRefPicMarking(H264SliceHeader
* shdr
) {
1034 if (shdr
->idr_pic_flag
) {
1035 READ_BOOL_OR_RETURN(&shdr
->no_output_of_prior_pics_flag
);
1036 READ_BOOL_OR_RETURN(&shdr
->long_term_reference_flag
);
1038 READ_BOOL_OR_RETURN(&shdr
->adaptive_ref_pic_marking_mode_flag
);
1040 H264DecRefPicMarking
* marking
;
1041 if (shdr
->adaptive_ref_pic_marking_mode_flag
) {
1043 for (i
= 0; i
< arraysize(shdr
->ref_pic_marking
); ++i
) {
1044 marking
= &shdr
->ref_pic_marking
[i
];
1046 READ_UE_OR_RETURN(&marking
->memory_mgmnt_control_operation
);
1047 if (marking
->memory_mgmnt_control_operation
== 0)
1050 if (marking
->memory_mgmnt_control_operation
== 1 ||
1051 marking
->memory_mgmnt_control_operation
== 3)
1052 READ_UE_OR_RETURN(&marking
->difference_of_pic_nums_minus1
);
1054 if (marking
->memory_mgmnt_control_operation
== 2)
1055 READ_UE_OR_RETURN(&marking
->long_term_pic_num
);
1057 if (marking
->memory_mgmnt_control_operation
== 3 ||
1058 marking
->memory_mgmnt_control_operation
== 6)
1059 READ_UE_OR_RETURN(&marking
->long_term_frame_idx
);
1061 if (marking
->memory_mgmnt_control_operation
== 4)
1062 READ_UE_OR_RETURN(&marking
->max_long_term_frame_idx_plus1
);
1064 if (marking
->memory_mgmnt_control_operation
> 6)
1065 return kInvalidStream
;
1068 if (i
== arraysize(shdr
->ref_pic_marking
)) {
1069 DVLOG(1) << "Ran out of dec ref pic marking fields";
1070 return kUnsupportedStream
;
1078 H264Parser::Result
H264Parser::ParseSliceHeader(const H264NALU
& nalu
,
1079 H264SliceHeader
* shdr
) {
1085 memset(shdr
, 0, sizeof(*shdr
));
1087 shdr
->idr_pic_flag
= (nalu
.nal_unit_type
== 5);
1088 shdr
->nal_ref_idc
= nalu
.nal_ref_idc
;
1089 shdr
->nalu_data
= nalu
.data
;
1090 shdr
->nalu_size
= nalu
.size
;
1092 READ_UE_OR_RETURN(&shdr
->first_mb_in_slice
);
1093 READ_UE_OR_RETURN(&shdr
->slice_type
);
1094 TRUE_OR_RETURN(shdr
->slice_type
< 10);
1096 READ_UE_OR_RETURN(&shdr
->pic_parameter_set_id
);
1098 pps
= GetPPS(shdr
->pic_parameter_set_id
);
1099 TRUE_OR_RETURN(pps
);
1101 sps
= GetSPS(pps
->seq_parameter_set_id
);
1102 TRUE_OR_RETURN(sps
);
1104 if (sps
->separate_colour_plane_flag
) {
1105 DVLOG(1) << "Interlaced streams not supported";
1106 return kUnsupportedStream
;
1109 READ_BITS_OR_RETURN(sps
->log2_max_frame_num_minus4
+ 4, &shdr
->frame_num
);
1110 if (!sps
->frame_mbs_only_flag
) {
1111 READ_BOOL_OR_RETURN(&shdr
->field_pic_flag
);
1112 if (shdr
->field_pic_flag
) {
1113 DVLOG(1) << "Interlaced streams not supported";
1114 return kUnsupportedStream
;
1118 if (shdr
->idr_pic_flag
)
1119 READ_UE_OR_RETURN(&shdr
->idr_pic_id
);
1121 if (sps
->pic_order_cnt_type
== 0) {
1122 READ_BITS_OR_RETURN(sps
->log2_max_pic_order_cnt_lsb_minus4
+ 4,
1123 &shdr
->pic_order_cnt_lsb
);
1124 if (pps
->bottom_field_pic_order_in_frame_present_flag
&&
1125 !shdr
->field_pic_flag
)
1126 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt_bottom
);
1129 if (sps
->pic_order_cnt_type
== 1 && !sps
->delta_pic_order_always_zero_flag
) {
1130 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt
[0]);
1131 if (pps
->bottom_field_pic_order_in_frame_present_flag
&&
1132 !shdr
->field_pic_flag
)
1133 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt
[1]);
1136 if (pps
->redundant_pic_cnt_present_flag
) {
1137 READ_UE_OR_RETURN(&shdr
->redundant_pic_cnt
);
1138 TRUE_OR_RETURN(shdr
->redundant_pic_cnt
< 128);
1141 if (shdr
->IsBSlice())
1142 READ_BOOL_OR_RETURN(&shdr
->direct_spatial_mv_pred_flag
);
1144 if (shdr
->IsPSlice() || shdr
->IsSPSlice() || shdr
->IsBSlice()) {
1145 READ_BOOL_OR_RETURN(&shdr
->num_ref_idx_active_override_flag
);
1146 if (shdr
->num_ref_idx_active_override_flag
) {
1147 READ_UE_OR_RETURN(&shdr
->num_ref_idx_l0_active_minus1
);
1148 if (shdr
->IsBSlice())
1149 READ_UE_OR_RETURN(&shdr
->num_ref_idx_l1_active_minus1
);
1151 shdr
->num_ref_idx_l0_active_minus1
=
1152 pps
->num_ref_idx_l0_default_active_minus1
;
1153 if (shdr
->IsBSlice()) {
1154 shdr
->num_ref_idx_l1_active_minus1
=
1155 pps
->num_ref_idx_l1_default_active_minus1
;
1159 if (shdr
->field_pic_flag
) {
1160 TRUE_OR_RETURN(shdr
->num_ref_idx_l0_active_minus1
< 32);
1161 TRUE_OR_RETURN(shdr
->num_ref_idx_l1_active_minus1
< 32);
1163 TRUE_OR_RETURN(shdr
->num_ref_idx_l0_active_minus1
< 16);
1164 TRUE_OR_RETURN(shdr
->num_ref_idx_l1_active_minus1
< 16);
1167 if (nalu
.nal_unit_type
== H264NALU::kCodedSliceExtension
) {
1168 return kUnsupportedStream
;
1170 res
= ParseRefPicListModifications(shdr
);
1175 if ((pps
->weighted_pred_flag
&& (shdr
->IsPSlice() || shdr
->IsSPSlice())) ||
1176 (pps
->weighted_bipred_idc
== 1 && shdr
->IsBSlice())) {
1177 res
= ParsePredWeightTable(*sps
, shdr
);
1182 if (nalu
.nal_ref_idc
!= 0) {
1183 res
= ParseDecRefPicMarking(shdr
);
1188 if (pps
->entropy_coding_mode_flag
&& !shdr
->IsISlice() &&
1189 !shdr
->IsSISlice()) {
1190 READ_UE_OR_RETURN(&shdr
->cabac_init_idc
);
1191 TRUE_OR_RETURN(shdr
->cabac_init_idc
< 3);
1194 READ_SE_OR_RETURN(&shdr
->slice_qp_delta
);
1196 if (shdr
->IsSPSlice() || shdr
->IsSISlice()) {
1197 if (shdr
->IsSPSlice())
1198 READ_BOOL_OR_RETURN(&shdr
->sp_for_switch_flag
);
1199 READ_SE_OR_RETURN(&shdr
->slice_qs_delta
);
1202 if (pps
->deblocking_filter_control_present_flag
) {
1203 READ_UE_OR_RETURN(&shdr
->disable_deblocking_filter_idc
);
1204 TRUE_OR_RETURN(shdr
->disable_deblocking_filter_idc
< 3);
1206 if (shdr
->disable_deblocking_filter_idc
!= 1) {
1207 READ_SE_OR_RETURN(&shdr
->slice_alpha_c0_offset_div2
);
1208 IN_RANGE_OR_RETURN(shdr
->slice_alpha_c0_offset_div2
, -6, 6);
1210 READ_SE_OR_RETURN(&shdr
->slice_beta_offset_div2
);
1211 IN_RANGE_OR_RETURN(shdr
->slice_beta_offset_div2
, -6, 6);
1215 if (pps
->num_slice_groups_minus1
> 0) {
1216 DVLOG(1) << "Slice groups not supported";
1217 return kUnsupportedStream
;
1220 size_t epb
= br_
.NumEmulationPreventionBytesRead();
1221 shdr
->header_bit_size
= (shdr
->nalu_size
- epb
) * 8 - br_
.NumBitsLeft();
1226 H264Parser::Result
H264Parser::ParseSEI(H264SEIMessage
* sei_msg
) {
1229 memset(sei_msg
, 0, sizeof(*sei_msg
));
1231 READ_BITS_OR_RETURN(8, &byte
);
1232 while (byte
== 0xff) {
1233 sei_msg
->type
+= 255;
1234 READ_BITS_OR_RETURN(8, &byte
);
1236 sei_msg
->type
+= byte
;
1238 READ_BITS_OR_RETURN(8, &byte
);
1239 while (byte
== 0xff) {
1240 sei_msg
->payload_size
+= 255;
1241 READ_BITS_OR_RETURN(8, &byte
);
1243 sei_msg
->payload_size
+= byte
;
1245 DVLOG(4) << "Found SEI message type: " << sei_msg
->type
1246 << " payload size: " << sei_msg
->payload_size
;
1248 switch (sei_msg
->type
) {
1249 case H264SEIMessage::kSEIRecoveryPoint
:
1250 READ_UE_OR_RETURN(&sei_msg
->recovery_point
.recovery_frame_cnt
);
1251 READ_BOOL_OR_RETURN(&sei_msg
->recovery_point
.exact_match_flag
);
1252 READ_BOOL_OR_RETURN(&sei_msg
->recovery_point
.broken_link_flag
);
1253 READ_BITS_OR_RETURN(2, &sei_msg
->recovery_point
.changing_slice_group_idc
);
1257 DVLOG(4) << "Unsupported SEI message";
1264 } // namespace media