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 static void FillDefaultSeqScalingLists(H264SPS
* sps
) {
583 for (int i
= 0; i
< 6; ++i
)
584 for (int j
= 0; j
< kH264ScalingList4x4Length
; ++j
)
585 sps
->scaling_list4x4
[i
][j
] = 16;
587 for (int i
= 0; i
< 6; ++i
)
588 for (int j
= 0; j
< kH264ScalingList8x8Length
; ++j
)
589 sps
->scaling_list8x8
[i
][j
] = 16;
592 H264Parser::Result
H264Parser::ParseSPS(int* sps_id
) {
599 scoped_ptr
<H264SPS
> sps(new H264SPS());
601 READ_BITS_OR_RETURN(8, &sps
->profile_idc
);
602 READ_BITS_OR_RETURN(6, &sps
->constraint_setx_flag
);
603 READ_BITS_OR_RETURN(2, &data
);
604 READ_BITS_OR_RETURN(8, &sps
->level_idc
);
605 READ_UE_OR_RETURN(&sps
->seq_parameter_set_id
);
606 TRUE_OR_RETURN(sps
->seq_parameter_set_id
< 32);
608 if (sps
->profile_idc
== 100 || sps
->profile_idc
== 110 ||
609 sps
->profile_idc
== 122 || sps
->profile_idc
== 244 ||
610 sps
->profile_idc
== 44 || sps
->profile_idc
== 83 ||
611 sps
->profile_idc
== 86 || sps
->profile_idc
== 118 ||
612 sps
->profile_idc
== 128) {
613 READ_UE_OR_RETURN(&sps
->chroma_format_idc
);
614 TRUE_OR_RETURN(sps
->chroma_format_idc
< 4);
616 if (sps
->chroma_format_idc
== 3)
617 READ_BOOL_OR_RETURN(&sps
->separate_colour_plane_flag
);
619 READ_UE_OR_RETURN(&sps
->bit_depth_luma_minus8
);
620 TRUE_OR_RETURN(sps
->bit_depth_luma_minus8
< 7);
622 READ_UE_OR_RETURN(&sps
->bit_depth_chroma_minus8
);
623 TRUE_OR_RETURN(sps
->bit_depth_chroma_minus8
< 7);
625 READ_BOOL_OR_RETURN(&sps
->qpprime_y_zero_transform_bypass_flag
);
626 READ_BOOL_OR_RETURN(&sps
->seq_scaling_matrix_present_flag
);
628 if (sps
->seq_scaling_matrix_present_flag
) {
629 DVLOG(4) << "Scaling matrix present";
630 res
= ParseSPSScalingLists(sps
.get());
634 FillDefaultSeqScalingLists(sps
.get());
637 sps
->chroma_format_idc
= 1;
638 FillDefaultSeqScalingLists(sps
.get());
641 if (sps
->separate_colour_plane_flag
)
642 sps
->chroma_array_type
= 0;
644 sps
->chroma_array_type
= sps
->chroma_format_idc
;
646 READ_UE_OR_RETURN(&sps
->log2_max_frame_num_minus4
);
647 TRUE_OR_RETURN(sps
->log2_max_frame_num_minus4
< 13);
649 READ_UE_OR_RETURN(&sps
->pic_order_cnt_type
);
650 TRUE_OR_RETURN(sps
->pic_order_cnt_type
< 3);
652 sps
->expected_delta_per_pic_order_cnt_cycle
= 0;
653 if (sps
->pic_order_cnt_type
== 0) {
654 READ_UE_OR_RETURN(&sps
->log2_max_pic_order_cnt_lsb_minus4
);
655 TRUE_OR_RETURN(sps
->log2_max_pic_order_cnt_lsb_minus4
< 13);
656 } else if (sps
->pic_order_cnt_type
== 1) {
657 READ_BOOL_OR_RETURN(&sps
->delta_pic_order_always_zero_flag
);
658 READ_SE_OR_RETURN(&sps
->offset_for_non_ref_pic
);
659 READ_SE_OR_RETURN(&sps
->offset_for_top_to_bottom_field
);
660 READ_UE_OR_RETURN(&sps
->num_ref_frames_in_pic_order_cnt_cycle
);
661 TRUE_OR_RETURN(sps
->num_ref_frames_in_pic_order_cnt_cycle
< 255);
663 for (int i
= 0; i
< sps
->num_ref_frames_in_pic_order_cnt_cycle
; ++i
) {
664 READ_SE_OR_RETURN(&sps
->offset_for_ref_frame
[i
]);
665 sps
->expected_delta_per_pic_order_cnt_cycle
+=
666 sps
->offset_for_ref_frame
[i
];
670 READ_UE_OR_RETURN(&sps
->max_num_ref_frames
);
671 READ_BOOL_OR_RETURN(&sps
->gaps_in_frame_num_value_allowed_flag
);
673 if (sps
->gaps_in_frame_num_value_allowed_flag
)
674 return kUnsupportedStream
;
676 READ_UE_OR_RETURN(&sps
->pic_width_in_mbs_minus1
);
677 READ_UE_OR_RETURN(&sps
->pic_height_in_map_units_minus1
);
679 READ_BOOL_OR_RETURN(&sps
->frame_mbs_only_flag
);
680 if (!sps
->frame_mbs_only_flag
)
681 READ_BOOL_OR_RETURN(&sps
->mb_adaptive_frame_field_flag
);
683 READ_BOOL_OR_RETURN(&sps
->direct_8x8_inference_flag
);
685 READ_BOOL_OR_RETURN(&sps
->frame_cropping_flag
);
686 if (sps
->frame_cropping_flag
) {
687 READ_UE_OR_RETURN(&sps
->frame_crop_left_offset
);
688 READ_UE_OR_RETURN(&sps
->frame_crop_right_offset
);
689 READ_UE_OR_RETURN(&sps
->frame_crop_top_offset
);
690 READ_UE_OR_RETURN(&sps
->frame_crop_bottom_offset
);
693 READ_BOOL_OR_RETURN(&sps
->vui_parameters_present_flag
);
694 if (sps
->vui_parameters_present_flag
) {
695 bool aspect_ratio_info_present_flag
;
696 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag
);
697 if (aspect_ratio_info_present_flag
) {
698 int aspect_ratio_idc
;
699 READ_BITS_OR_RETURN(8, &aspect_ratio_idc
);
700 if (aspect_ratio_idc
== kExtendedSar
) {
701 READ_BITS_OR_RETURN(16, &sps
->sar_width
);
702 READ_BITS_OR_RETURN(16, &sps
->sar_height
);
704 const int max_aspect_ratio_idc
= arraysize(kTableSarWidth
) - 1;
705 IN_RANGE_OR_RETURN(aspect_ratio_idc
, 0, max_aspect_ratio_idc
);
706 sps
->sar_width
= kTableSarWidth
[aspect_ratio_idc
];
707 sps
->sar_height
= kTableSarHeight
[aspect_ratio_idc
];
712 // If an SPS with the same id already exists, replace it.
713 *sps_id
= sps
->seq_parameter_set_id
;
714 delete active_SPSes_
[*sps_id
];
715 active_SPSes_
[*sps_id
] = sps
.release();
720 H264Parser::Result
H264Parser::ParsePPS(int* pps_id
) {
727 scoped_ptr
<H264PPS
> pps(new H264PPS());
729 READ_UE_OR_RETURN(&pps
->pic_parameter_set_id
);
730 READ_UE_OR_RETURN(&pps
->seq_parameter_set_id
);
731 TRUE_OR_RETURN(pps
->seq_parameter_set_id
< 32);
733 sps
= GetSPS(pps
->seq_parameter_set_id
);
736 READ_BOOL_OR_RETURN(&pps
->entropy_coding_mode_flag
);
737 READ_BOOL_OR_RETURN(&pps
->bottom_field_pic_order_in_frame_present_flag
);
739 READ_UE_OR_RETURN(&pps
->num_slice_groups_minus1
);
740 if (pps
->num_slice_groups_minus1
> 1) {
741 DVLOG(1) << "Slice groups not supported";
742 return kUnsupportedStream
;
745 READ_UE_OR_RETURN(&pps
->num_ref_idx_l0_default_active_minus1
);
746 TRUE_OR_RETURN(pps
->num_ref_idx_l0_default_active_minus1
< 32);
748 READ_UE_OR_RETURN(&pps
->num_ref_idx_l1_default_active_minus1
);
749 TRUE_OR_RETURN(pps
->num_ref_idx_l1_default_active_minus1
< 32);
751 READ_BOOL_OR_RETURN(&pps
->weighted_pred_flag
);
752 READ_BITS_OR_RETURN(2, &pps
->weighted_bipred_idc
);
753 TRUE_OR_RETURN(pps
->weighted_bipred_idc
< 3);
755 READ_SE_OR_RETURN(&pps
->pic_init_qp_minus26
);
756 IN_RANGE_OR_RETURN(pps
->pic_init_qp_minus26
, -26, 25);
758 READ_SE_OR_RETURN(&pps
->pic_init_qs_minus26
);
759 IN_RANGE_OR_RETURN(pps
->pic_init_qs_minus26
, -26, 25);
761 READ_SE_OR_RETURN(&pps
->chroma_qp_index_offset
);
762 IN_RANGE_OR_RETURN(pps
->chroma_qp_index_offset
, -12, 12);
763 pps
->second_chroma_qp_index_offset
= pps
->chroma_qp_index_offset
;
765 READ_BOOL_OR_RETURN(&pps
->deblocking_filter_control_present_flag
);
766 READ_BOOL_OR_RETURN(&pps
->constrained_intra_pred_flag
);
767 READ_BOOL_OR_RETURN(&pps
->redundant_pic_cnt_present_flag
);
769 if (br_
.HasMoreRBSPData()) {
770 READ_BOOL_OR_RETURN(&pps
->transform_8x8_mode_flag
);
771 READ_BOOL_OR_RETURN(&pps
->pic_scaling_matrix_present_flag
);
773 if (pps
->pic_scaling_matrix_present_flag
) {
774 DVLOG(4) << "Picture scaling matrix present";
775 res
= ParsePPSScalingLists(*sps
, pps
.get());
780 READ_SE_OR_RETURN(&pps
->second_chroma_qp_index_offset
);
783 // If a PPS with the same id already exists, replace it.
784 *pps_id
= pps
->pic_parameter_set_id
;
785 delete active_PPSes_
[*pps_id
];
786 active_PPSes_
[*pps_id
] = pps
.release();
791 H264Parser::Result
H264Parser::ParseRefPicListModification(
792 int num_ref_idx_active_minus1
,
793 H264ModificationOfPicNum
* ref_list_mods
) {
794 H264ModificationOfPicNum
* pic_num_mod
;
796 if (num_ref_idx_active_minus1
>= 32)
797 return kInvalidStream
;
799 for (int i
= 0; i
< 32; ++i
) {
800 pic_num_mod
= &ref_list_mods
[i
];
801 READ_UE_OR_RETURN(&pic_num_mod
->modification_of_pic_nums_idc
);
802 TRUE_OR_RETURN(pic_num_mod
->modification_of_pic_nums_idc
< 4);
804 switch (pic_num_mod
->modification_of_pic_nums_idc
) {
807 READ_UE_OR_RETURN(&pic_num_mod
->abs_diff_pic_num_minus1
);
811 READ_UE_OR_RETURN(&pic_num_mod
->long_term_pic_num
);
815 // Per spec, list cannot be empty.
817 return kInvalidStream
;
821 return kInvalidStream
;
825 // If we got here, we didn't get loop end marker prematurely,
826 // so make sure it is there for our client.
827 int modification_of_pic_nums_idc
;
828 READ_UE_OR_RETURN(&modification_of_pic_nums_idc
);
829 TRUE_OR_RETURN(modification_of_pic_nums_idc
== 3);
834 H264Parser::Result
H264Parser::ParseRefPicListModifications(
835 H264SliceHeader
* shdr
) {
838 if (!shdr
->IsISlice() && !shdr
->IsSISlice()) {
839 READ_BOOL_OR_RETURN(&shdr
->ref_pic_list_modification_flag_l0
);
840 if (shdr
->ref_pic_list_modification_flag_l0
) {
841 res
= ParseRefPicListModification(shdr
->num_ref_idx_l0_active_minus1
,
842 shdr
->ref_list_l0_modifications
);
848 if (shdr
->IsBSlice()) {
849 READ_BOOL_OR_RETURN(&shdr
->ref_pic_list_modification_flag_l1
);
850 if (shdr
->ref_pic_list_modification_flag_l1
) {
851 res
= ParseRefPicListModification(shdr
->num_ref_idx_l1_active_minus1
,
852 shdr
->ref_list_l1_modifications
);
861 H264Parser::Result
H264Parser::ParseWeightingFactors(
862 int num_ref_idx_active_minus1
,
863 int chroma_array_type
,
864 int luma_log2_weight_denom
,
865 int chroma_log2_weight_denom
,
866 H264WeightingFactors
* w_facts
) {
868 int def_luma_weight
= 1 << luma_log2_weight_denom
;
869 int def_chroma_weight
= 1 << chroma_log2_weight_denom
;
871 for (int i
= 0; i
< num_ref_idx_active_minus1
+ 1; ++i
) {
872 READ_BOOL_OR_RETURN(&w_facts
->luma_weight_flag
);
873 if (w_facts
->luma_weight_flag
) {
874 READ_SE_OR_RETURN(&w_facts
->luma_weight
[i
]);
875 IN_RANGE_OR_RETURN(w_facts
->luma_weight
[i
], -128, 127);
877 READ_SE_OR_RETURN(&w_facts
->luma_offset
[i
]);
878 IN_RANGE_OR_RETURN(w_facts
->luma_offset
[i
], -128, 127);
880 w_facts
->luma_weight
[i
] = def_luma_weight
;
881 w_facts
->luma_offset
[i
] = 0;
884 if (chroma_array_type
!= 0) {
885 READ_BOOL_OR_RETURN(&w_facts
->chroma_weight_flag
);
886 if (w_facts
->chroma_weight_flag
) {
887 for (int j
= 0; j
< 2; ++j
) {
888 READ_SE_OR_RETURN(&w_facts
->chroma_weight
[i
][j
]);
889 IN_RANGE_OR_RETURN(w_facts
->chroma_weight
[i
][j
], -128, 127);
891 READ_SE_OR_RETURN(&w_facts
->chroma_offset
[i
][j
]);
892 IN_RANGE_OR_RETURN(w_facts
->chroma_offset
[i
][j
], -128, 127);
895 for (int j
= 0; j
< 2; ++j
) {
896 w_facts
->chroma_weight
[i
][j
] = def_chroma_weight
;
897 w_facts
->chroma_offset
[i
][j
] = 0;
906 H264Parser::Result
H264Parser::ParsePredWeightTable(const H264SPS
& sps
,
907 H264SliceHeader
* shdr
) {
908 READ_UE_OR_RETURN(&shdr
->luma_log2_weight_denom
);
909 TRUE_OR_RETURN(shdr
->luma_log2_weight_denom
< 8);
911 if (sps
.chroma_array_type
!= 0)
912 READ_UE_OR_RETURN(&shdr
->chroma_log2_weight_denom
);
913 TRUE_OR_RETURN(shdr
->chroma_log2_weight_denom
< 8);
915 Result res
= ParseWeightingFactors(shdr
->num_ref_idx_l0_active_minus1
,
916 sps
.chroma_array_type
,
917 shdr
->luma_log2_weight_denom
,
918 shdr
->chroma_log2_weight_denom
,
919 &shdr
->pred_weight_table_l0
);
923 if (shdr
->IsBSlice()) {
924 res
= ParseWeightingFactors(shdr
->num_ref_idx_l1_active_minus1
,
925 sps
.chroma_array_type
,
926 shdr
->luma_log2_weight_denom
,
927 shdr
->chroma_log2_weight_denom
,
928 &shdr
->pred_weight_table_l1
);
936 H264Parser::Result
H264Parser::ParseDecRefPicMarking(H264SliceHeader
* shdr
) {
937 if (shdr
->idr_pic_flag
) {
938 READ_BOOL_OR_RETURN(&shdr
->no_output_of_prior_pics_flag
);
939 READ_BOOL_OR_RETURN(&shdr
->long_term_reference_flag
);
941 READ_BOOL_OR_RETURN(&shdr
->adaptive_ref_pic_marking_mode_flag
);
943 H264DecRefPicMarking
* marking
;
944 if (shdr
->adaptive_ref_pic_marking_mode_flag
) {
946 for (i
= 0; i
< arraysize(shdr
->ref_pic_marking
); ++i
) {
947 marking
= &shdr
->ref_pic_marking
[i
];
949 READ_UE_OR_RETURN(&marking
->memory_mgmnt_control_operation
);
950 if (marking
->memory_mgmnt_control_operation
== 0)
953 if (marking
->memory_mgmnt_control_operation
== 1 ||
954 marking
->memory_mgmnt_control_operation
== 3)
955 READ_UE_OR_RETURN(&marking
->difference_of_pic_nums_minus1
);
957 if (marking
->memory_mgmnt_control_operation
== 2)
958 READ_UE_OR_RETURN(&marking
->long_term_pic_num
);
960 if (marking
->memory_mgmnt_control_operation
== 3 ||
961 marking
->memory_mgmnt_control_operation
== 6)
962 READ_UE_OR_RETURN(&marking
->long_term_frame_idx
);
964 if (marking
->memory_mgmnt_control_operation
== 4)
965 READ_UE_OR_RETURN(&marking
->max_long_term_frame_idx_plus1
);
967 if (marking
->memory_mgmnt_control_operation
> 6)
968 return kInvalidStream
;
971 if (i
== arraysize(shdr
->ref_pic_marking
)) {
972 DVLOG(1) << "Ran out of dec ref pic marking fields";
973 return kUnsupportedStream
;
981 H264Parser::Result
H264Parser::ParseSliceHeader(const H264NALU
& nalu
,
982 H264SliceHeader
* shdr
) {
988 memset(shdr
, 0, sizeof(*shdr
));
990 shdr
->idr_pic_flag
= (nalu
.nal_unit_type
== 5);
991 shdr
->nal_ref_idc
= nalu
.nal_ref_idc
;
992 shdr
->nalu_data
= nalu
.data
;
993 shdr
->nalu_size
= nalu
.size
;
995 READ_UE_OR_RETURN(&shdr
->first_mb_in_slice
);
996 READ_UE_OR_RETURN(&shdr
->slice_type
);
997 TRUE_OR_RETURN(shdr
->slice_type
< 10);
999 READ_UE_OR_RETURN(&shdr
->pic_parameter_set_id
);
1001 pps
= GetPPS(shdr
->pic_parameter_set_id
);
1002 TRUE_OR_RETURN(pps
);
1004 sps
= GetSPS(pps
->seq_parameter_set_id
);
1005 TRUE_OR_RETURN(sps
);
1007 if (sps
->separate_colour_plane_flag
) {
1008 DVLOG(1) << "Interlaced streams not supported";
1009 return kUnsupportedStream
;
1012 READ_BITS_OR_RETURN(sps
->log2_max_frame_num_minus4
+ 4, &shdr
->frame_num
);
1013 if (!sps
->frame_mbs_only_flag
) {
1014 READ_BOOL_OR_RETURN(&shdr
->field_pic_flag
);
1015 if (shdr
->field_pic_flag
) {
1016 DVLOG(1) << "Interlaced streams not supported";
1017 return kUnsupportedStream
;
1021 if (shdr
->idr_pic_flag
)
1022 READ_UE_OR_RETURN(&shdr
->idr_pic_id
);
1024 if (sps
->pic_order_cnt_type
== 0) {
1025 READ_BITS_OR_RETURN(sps
->log2_max_pic_order_cnt_lsb_minus4
+ 4,
1026 &shdr
->pic_order_cnt_lsb
);
1027 if (pps
->bottom_field_pic_order_in_frame_present_flag
&&
1028 !shdr
->field_pic_flag
)
1029 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt_bottom
);
1032 if (sps
->pic_order_cnt_type
== 1 && !sps
->delta_pic_order_always_zero_flag
) {
1033 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt
[0]);
1034 if (pps
->bottom_field_pic_order_in_frame_present_flag
&&
1035 !shdr
->field_pic_flag
)
1036 READ_SE_OR_RETURN(&shdr
->delta_pic_order_cnt
[1]);
1039 if (pps
->redundant_pic_cnt_present_flag
) {
1040 READ_UE_OR_RETURN(&shdr
->redundant_pic_cnt
);
1041 TRUE_OR_RETURN(shdr
->redundant_pic_cnt
< 128);
1044 if (shdr
->IsBSlice())
1045 READ_BOOL_OR_RETURN(&shdr
->direct_spatial_mv_pred_flag
);
1047 if (shdr
->IsPSlice() || shdr
->IsSPSlice() || shdr
->IsBSlice()) {
1048 READ_BOOL_OR_RETURN(&shdr
->num_ref_idx_active_override_flag
);
1049 if (shdr
->num_ref_idx_active_override_flag
) {
1050 READ_UE_OR_RETURN(&shdr
->num_ref_idx_l0_active_minus1
);
1051 if (shdr
->IsBSlice())
1052 READ_UE_OR_RETURN(&shdr
->num_ref_idx_l1_active_minus1
);
1054 shdr
->num_ref_idx_l0_active_minus1
=
1055 pps
->num_ref_idx_l0_default_active_minus1
;
1056 if (shdr
->IsBSlice()) {
1057 shdr
->num_ref_idx_l1_active_minus1
=
1058 pps
->num_ref_idx_l1_default_active_minus1
;
1062 if (shdr
->field_pic_flag
) {
1063 TRUE_OR_RETURN(shdr
->num_ref_idx_l0_active_minus1
< 32);
1064 TRUE_OR_RETURN(shdr
->num_ref_idx_l1_active_minus1
< 32);
1066 TRUE_OR_RETURN(shdr
->num_ref_idx_l0_active_minus1
< 16);
1067 TRUE_OR_RETURN(shdr
->num_ref_idx_l1_active_minus1
< 16);
1070 if (nalu
.nal_unit_type
== H264NALU::kCodedSliceExtension
) {
1071 return kUnsupportedStream
;
1073 res
= ParseRefPicListModifications(shdr
);
1078 if ((pps
->weighted_pred_flag
&& (shdr
->IsPSlice() || shdr
->IsSPSlice())) ||
1079 (pps
->weighted_bipred_idc
== 1 && shdr
->IsBSlice())) {
1080 res
= ParsePredWeightTable(*sps
, shdr
);
1085 if (nalu
.nal_ref_idc
!= 0) {
1086 res
= ParseDecRefPicMarking(shdr
);
1091 if (pps
->entropy_coding_mode_flag
&& !shdr
->IsISlice() &&
1092 !shdr
->IsSISlice()) {
1093 READ_UE_OR_RETURN(&shdr
->cabac_init_idc
);
1094 TRUE_OR_RETURN(shdr
->cabac_init_idc
< 3);
1097 READ_SE_OR_RETURN(&shdr
->slice_qp_delta
);
1099 if (shdr
->IsSPSlice() || shdr
->IsSISlice()) {
1100 if (shdr
->IsSPSlice())
1101 READ_BOOL_OR_RETURN(&shdr
->sp_for_switch_flag
);
1102 READ_SE_OR_RETURN(&shdr
->slice_qs_delta
);
1105 if (pps
->deblocking_filter_control_present_flag
) {
1106 READ_UE_OR_RETURN(&shdr
->disable_deblocking_filter_idc
);
1107 TRUE_OR_RETURN(shdr
->disable_deblocking_filter_idc
< 3);
1109 if (shdr
->disable_deblocking_filter_idc
!= 1) {
1110 READ_SE_OR_RETURN(&shdr
->slice_alpha_c0_offset_div2
);
1111 IN_RANGE_OR_RETURN(shdr
->slice_alpha_c0_offset_div2
, -6, 6);
1113 READ_SE_OR_RETURN(&shdr
->slice_beta_offset_div2
);
1114 IN_RANGE_OR_RETURN(shdr
->slice_beta_offset_div2
, -6, 6);
1118 if (pps
->num_slice_groups_minus1
> 0) {
1119 DVLOG(1) << "Slice groups not supported";
1120 return kUnsupportedStream
;
1123 size_t epb
= br_
.NumEmulationPreventionBytesRead();
1124 shdr
->header_bit_size
= (shdr
->nalu_size
- epb
) * 8 - br_
.NumBitsLeft();
1129 H264Parser::Result
H264Parser::ParseSEI(H264SEIMessage
* sei_msg
) {
1132 memset(sei_msg
, 0, sizeof(*sei_msg
));
1134 READ_BITS_OR_RETURN(8, &byte
);
1135 while (byte
== 0xff) {
1136 sei_msg
->type
+= 255;
1137 READ_BITS_OR_RETURN(8, &byte
);
1139 sei_msg
->type
+= byte
;
1141 READ_BITS_OR_RETURN(8, &byte
);
1142 while (byte
== 0xff) {
1143 sei_msg
->payload_size
+= 255;
1144 READ_BITS_OR_RETURN(8, &byte
);
1146 sei_msg
->payload_size
+= byte
;
1148 DVLOG(4) << "Found SEI message type: " << sei_msg
->type
1149 << " payload size: " << sei_msg
->payload_size
;
1151 switch (sei_msg
->type
) {
1152 case H264SEIMessage::kSEIRecoveryPoint
:
1153 READ_UE_OR_RETURN(&sei_msg
->recovery_point
.recovery_frame_cnt
);
1154 READ_BOOL_OR_RETURN(&sei_msg
->recovery_point
.exact_match_flag
);
1155 READ_BOOL_OR_RETURN(&sei_msg
->recovery_point
.broken_link_flag
);
1156 READ_BITS_OR_RETURN(2, &sei_msg
->recovery_point
.changing_slice_group_idc
);
1160 DVLOG(4) << "Unsupported SEI message";
1167 } // namespace media