5 #include "packager/media/filters/h264_parser.h"
7 #include "packager/base/logging.h"
8 #include "packager/base/memory/scoped_ptr.h"
9 #include "packager/base/stl_util.h"
10 #include "packager/media/base/buffer_reader.h"
12 namespace edash_packager {
17 bool ExtractResolutionFromSps(
const H264SPS& sps,
18 uint32_t* coded_width,
19 uint32_t* coded_height,
20 uint32_t* pixel_width,
21 uint32_t* pixel_height) {
24 if (sps.frame_cropping_flag) {
28 switch (sps.chroma_format_idc) {
48 LOG(ERROR) <<
"Unexpected chroma_format_idc " << sps.chroma_format_idc;
53 int crop_unit_x = sub_width_c;
54 int crop_unit_y = sub_height_c * (2 - (sps.frame_mbs_only_flag ? 1 : 0));
55 crop_x = crop_unit_x *
56 (sps.frame_crop_left_offset + sps.frame_crop_right_offset);
57 crop_y = crop_unit_y *
58 (sps.frame_crop_top_offset + sps.frame_crop_bottom_offset);
62 int pic_width_in_mbs = sps.pic_width_in_mbs_minus1 + 1;
63 *coded_width = pic_width_in_mbs * 16 - crop_x;
66 int pic_height_in_mbs = (2 - (sps.frame_mbs_only_flag ? 1 : 0)) *
67 (sps.pic_height_in_map_units_minus1 + 1);
68 *coded_height = pic_height_in_mbs * 16 - crop_y;
71 *pixel_width = sps.sar_width == 0 ? 1 : sps.sar_width;
72 *pixel_height = sps.sar_height == 0 ? 1 : sps.sar_height;
73 DVLOG(2) <<
"Found coded_width: " << *coded_width
74 <<
" coded_height: " << *coded_height
75 <<
" pixel_width: " << *pixel_width
76 <<
" pixel_height: " << *pixel_height;
80 bool H264SliceHeader::IsPSlice()
const {
81 return (slice_type % 5 == kPSlice);
84 bool H264SliceHeader::IsBSlice()
const {
85 return (slice_type % 5 == kBSlice);
88 bool H264SliceHeader::IsISlice()
const {
89 return (slice_type % 5 == kISlice);
92 bool H264SliceHeader::IsSPSlice()
const {
93 return (slice_type % 5 == kSPSlice);
96 bool H264SliceHeader::IsSISlice()
const {
97 return (slice_type % 5 == kSISlice);
101 memset(
this, 0,
sizeof(*
this));
105 memset(
this, 0,
sizeof(*
this));
108 H264SliceHeader::H264SliceHeader() {
109 memset(
this, 0,
sizeof(*
this));
112 H264SEIMessage::H264SEIMessage() {
113 memset(
this, 0,
sizeof(*
this));
116 #define READ_BITS_OR_RETURN(num_bits, out) \
118 if (!br->ReadBits(num_bits, (out))) { \
120 << "Error in stream: unexpected EOS while trying to read " #out; \
121 return kInvalidStream; \
125 #define READ_BOOL_OR_RETURN(out) \
128 if (!br->ReadBits(1, &_out)) { \
130 << "Error in stream: unexpected EOS while trying to read " #out; \
131 return kInvalidStream; \
133 *(out) = _out != 0; \
136 #define READ_UE_OR_RETURN(out) \
138 if (!br->ReadUE(out)) { \
139 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
140 return kInvalidStream; \
144 #define READ_SE_OR_RETURN(out) \
146 if (!br->ReadSE(out)) { \
147 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
148 return kInvalidStream; \
152 #define IN_RANGE_OR_RETURN(val, min, max) \
154 if ((val) < (min) || (val) > (max)) { \
155 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
156 << " in range [" << (min) << ":" << (max) << "]" \
157 << " found " << (val) << " instead"; \
158 return kInvalidStream; \
162 #define TRUE_OR_RETURN(a) \
165 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
166 return kInvalidStream; \
170 enum AspectRatioIdc {
176 static const int kTableSarWidth[] = {
177 0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
179 static const int kTableSarHeight[] = {
180 0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
182 COMPILE_ASSERT(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
183 sar_tables_must_have_same_size);
185 H264Parser::H264Parser() {}
187 H264Parser::~H264Parser() {
188 STLDeleteValues(&active_SPSes_);
189 STLDeleteValues(&active_PPSes_);
192 const H264PPS* H264Parser::GetPPS(
int pps_id) {
193 return active_PPSes_[pps_id];
196 const H264SPS* H264Parser::GetSPS(
int sps_id) {
197 return active_SPSes_[sps_id];
201 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
202 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
204 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
205 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
207 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
208 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
209 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
210 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
211 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
213 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
214 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
215 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
216 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
217 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
219 static inline void DefaultScalingList4x4(
221 int scaling_list4x4[][kH264ScalingList4x4Length]) {
225 memcpy(scaling_list4x4[i], kDefault4x4Intra,
sizeof(kDefault4x4Intra));
227 memcpy(scaling_list4x4[i], kDefault4x4Inter,
sizeof(kDefault4x4Inter));
230 static inline void DefaultScalingList8x8(
232 int scaling_list8x8[][kH264ScalingList8x8Length]) {
236 memcpy(scaling_list8x8[i], kDefault8x8Intra,
sizeof(kDefault8x8Intra));
238 memcpy(scaling_list8x8[i], kDefault8x8Inter,
sizeof(kDefault8x8Inter));
241 static void FallbackScalingList4x4(
243 const int default_scaling_list_intra[],
244 const int default_scaling_list_inter[],
245 int scaling_list4x4[][kH264ScalingList4x4Length]) {
246 static const int kScalingList4x4ByteSize =
247 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
251 memcpy(scaling_list4x4[i], default_scaling_list_intra,
252 kScalingList4x4ByteSize);
256 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
260 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
264 memcpy(scaling_list4x4[i], default_scaling_list_inter,
265 kScalingList4x4ByteSize);
269 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
273 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
282 static void FallbackScalingList8x8(
284 const int default_scaling_list_intra[],
285 const int default_scaling_list_inter[],
286 int scaling_list8x8[][kH264ScalingList8x8Length]) {
287 static const int kScalingList8x8ByteSize =
288 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
292 memcpy(scaling_list8x8[i], default_scaling_list_intra,
293 kScalingList8x8ByteSize);
297 memcpy(scaling_list8x8[i], default_scaling_list_inter,
298 kScalingList8x8ByteSize);
302 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
306 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
310 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
314 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
323 H264Parser::Result H264Parser::ParseScalingList(H264BitReader* br,
332 *use_default =
false;
334 for (
int j = 0; j < size; ++j) {
335 if (next_scale != 0) {
336 READ_SE_OR_RETURN(&delta_scale);
337 IN_RANGE_OR_RETURN(delta_scale, -128, 127);
338 next_scale = (last_scale + delta_scale + 256) & 0xff;
340 if (j == 0 && next_scale == 0) {
346 scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
347 last_scale = scaling_list[j];
353 H264Parser::Result H264Parser::ParseSPSScalingLists(H264BitReader* br,
356 bool seq_scaling_list_present_flag;
361 for (
int i = 0; i < 6; ++i) {
362 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
364 if (seq_scaling_list_present_flag) {
365 res = ParseScalingList(br,
366 arraysize(sps->scaling_list4x4[i]),
367 sps->scaling_list4x4[i],
373 DefaultScalingList4x4(i, sps->scaling_list4x4);
376 FallbackScalingList4x4(
377 i, kDefault4x4Intra, kDefault4x4Inter, sps->scaling_list4x4);
382 for (
int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
383 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
385 if (seq_scaling_list_present_flag) {
386 res = ParseScalingList(br,
387 arraysize(sps->scaling_list8x8[i]),
388 sps->scaling_list8x8[i],
394 DefaultScalingList8x8(i, sps->scaling_list8x8);
397 FallbackScalingList8x8(
398 i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8);
405 H264Parser::Result H264Parser::ParsePPSScalingLists(H264BitReader* br,
409 bool pic_scaling_list_present_flag;
413 for (
int i = 0; i < 6; ++i) {
414 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
416 if (pic_scaling_list_present_flag) {
417 res = ParseScalingList(br,
418 arraysize(pps->scaling_list4x4[i]),
419 pps->scaling_list4x4[i],
425 DefaultScalingList4x4(i, pps->scaling_list4x4);
428 if (sps.seq_scaling_matrix_present_flag) {
430 FallbackScalingList4x4(
431 i, kDefault4x4Intra, kDefault4x4Inter, pps->scaling_list4x4);
434 FallbackScalingList4x4(i,
435 sps.scaling_list4x4[0],
436 sps.scaling_list4x4[3],
437 pps->scaling_list4x4);
442 if (pps->transform_8x8_mode_flag) {
443 for (
int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
444 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
446 if (pic_scaling_list_present_flag) {
447 res = ParseScalingList(br,
448 arraysize(pps->scaling_list8x8[i]),
449 pps->scaling_list8x8[i],
455 DefaultScalingList8x8(i, pps->scaling_list8x8);
458 if (sps.seq_scaling_matrix_present_flag) {
460 FallbackScalingList8x8(
461 i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8);
464 FallbackScalingList8x8(i,
465 sps.scaling_list8x8[0],
466 sps.scaling_list8x8[1],
467 pps->scaling_list8x8);
475 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
476 H264BitReader* br,
bool* hrd_parameters_present) {
478 READ_BOOL_OR_RETURN(&data);
482 *hrd_parameters_present =
true;
485 READ_UE_OR_RETURN(&cpb_cnt_minus1);
486 IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
487 READ_BITS_OR_RETURN(8, &data);
488 for (
int i = 0; i <= cpb_cnt_minus1; ++i) {
489 READ_UE_OR_RETURN(&data);
490 READ_UE_OR_RETURN(&data);
491 READ_BOOL_OR_RETURN(&data);
493 READ_BITS_OR_RETURN(20, &data);
498 H264Parser::Result H264Parser::ParseVUIParameters(H264BitReader* br,
500 bool aspect_ratio_info_present_flag;
501 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
502 if (aspect_ratio_info_present_flag) {
503 int aspect_ratio_idc;
504 READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
505 if (aspect_ratio_idc == kExtendedSar) {
506 READ_BITS_OR_RETURN(16, &sps->sar_width);
507 READ_BITS_OR_RETURN(16, &sps->sar_height);
509 const int max_aspect_ratio_idc = arraysize(kTableSarWidth) - 1;
510 IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
511 sps->sar_width = kTableSarWidth[aspect_ratio_idc];
512 sps->sar_height = kTableSarHeight[aspect_ratio_idc];
518 READ_BOOL_OR_RETURN(&data);
520 READ_BOOL_OR_RETURN(&data);
522 READ_BOOL_OR_RETURN(&data);
524 READ_BITS_OR_RETURN(3, &data);
525 READ_BOOL_OR_RETURN(&data);
526 READ_BOOL_OR_RETURN(&data);
528 READ_BITS_OR_RETURN(24, &data);
531 READ_BOOL_OR_RETURN(&data);
533 READ_UE_OR_RETURN(&data);
534 READ_UE_OR_RETURN(&data);
538 READ_BOOL_OR_RETURN(&data);
540 READ_BITS_OR_RETURN(16, &data);
541 READ_BITS_OR_RETURN(16, &data);
542 READ_BITS_OR_RETURN(16, &data);
543 READ_BITS_OR_RETURN(16, &data);
544 READ_BOOL_OR_RETURN(&data);
548 bool hrd_parameters_present =
false;
549 Result res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
554 res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
558 if (hrd_parameters_present)
559 READ_BOOL_OR_RETURN(&data);
561 READ_BOOL_OR_RETURN(&data);
562 READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
563 if (sps->bitstream_restriction_flag) {
564 READ_BOOL_OR_RETURN(&data);
565 READ_UE_OR_RETURN(&data);
566 READ_UE_OR_RETURN(&data);
567 READ_UE_OR_RETURN(&data);
568 READ_UE_OR_RETURN(&data);
569 READ_UE_OR_RETURN(&sps->max_num_reorder_frames);
570 READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
571 TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
573 sps->max_num_reorder_frames, 0, sps->max_dec_frame_buffering);
579 static void FillDefaultSeqScalingLists(H264SPS* sps) {
580 for (
int i = 0; i < 6; ++i)
581 for (
int j = 0; j < kH264ScalingList4x4Length; ++j)
582 sps->scaling_list4x4[i][j] = 16;
584 for (
int i = 0; i < 6; ++i)
585 for (
int j = 0; j < kH264ScalingList8x8Length; ++j)
586 sps->scaling_list8x8[i][j] = 16;
589 H264Parser::Result H264Parser::ParseSPS(
const Nalu& nalu,
int* sps_id) {
593 H264BitReader reader;
594 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
595 H264BitReader* br = &reader;
599 scoped_ptr<H264SPS> sps(
new H264SPS());
601 READ_BITS_OR_RETURN(8, &sps->profile_idc);
602 READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
603 READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
604 READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
605 READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
606 READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
607 READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
608 READ_BITS_OR_RETURN(2, &data);
609 READ_BITS_OR_RETURN(8, &sps->level_idc);
610 READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
611 TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
613 if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
614 sps->profile_idc == 122 || sps->profile_idc == 244 ||
615 sps->profile_idc == 44 || sps->profile_idc == 83 ||
616 sps->profile_idc == 86 || sps->profile_idc == 118 ||
617 sps->profile_idc == 128) {
618 READ_UE_OR_RETURN(&sps->chroma_format_idc);
619 TRUE_OR_RETURN(sps->chroma_format_idc < 4);
621 if (sps->chroma_format_idc == 3)
622 READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
624 READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
625 TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
627 READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
628 TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
630 READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
631 READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
633 if (sps->seq_scaling_matrix_present_flag) {
634 DVLOG(4) <<
"Scaling matrix present";
635 res = ParseSPSScalingLists(br, sps.get());
639 FillDefaultSeqScalingLists(sps.get());
642 sps->chroma_format_idc = 1;
643 FillDefaultSeqScalingLists(sps.get());
646 if (sps->separate_colour_plane_flag)
647 sps->chroma_array_type = 0;
649 sps->chroma_array_type = sps->chroma_format_idc;
651 READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
652 TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
654 READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
655 TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
657 sps->expected_delta_per_pic_order_cnt_cycle = 0;
658 if (sps->pic_order_cnt_type == 0) {
659 READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
660 TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
661 }
else if (sps->pic_order_cnt_type == 1) {
662 READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
663 READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
664 READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
665 READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
666 TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
668 for (
int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
669 READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
670 sps->expected_delta_per_pic_order_cnt_cycle +=
671 sps->offset_for_ref_frame[i];
675 READ_UE_OR_RETURN(&sps->max_num_ref_frames);
676 READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
678 if (sps->gaps_in_frame_num_value_allowed_flag)
679 return kUnsupportedStream;
681 READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
682 READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
684 READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
685 if (!sps->frame_mbs_only_flag)
686 READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
688 READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
690 READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
691 if (sps->frame_cropping_flag) {
692 READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
693 READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
694 READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
695 READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
698 READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
699 if (sps->vui_parameters_present_flag) {
700 DVLOG(4) <<
"VUI parameters present";
701 res = ParseVUIParameters(br, sps.get());
707 *sps_id = sps->seq_parameter_set_id;
708 delete active_SPSes_[*sps_id];
709 active_SPSes_[*sps_id] = sps.release();
714 H264Parser::Result H264Parser::ParsePPS(
const Nalu& nalu,
int* pps_id) {
718 H264BitReader reader;
719 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
720 H264BitReader* br = &reader;
724 scoped_ptr<H264PPS> pps(
new H264PPS());
726 READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
727 READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
728 TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
730 sps = GetSPS(pps->seq_parameter_set_id);
733 READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
734 READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
736 READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
737 if (pps->num_slice_groups_minus1 > 1) {
738 DVLOG(1) <<
"Slice groups not supported";
739 return kUnsupportedStream;
742 READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
743 TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
745 READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
746 TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
748 READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
749 READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
750 TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
752 READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
753 IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
755 READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
756 IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
758 READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
759 IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
760 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
762 READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
763 READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
764 READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
766 if (br->HasMoreRBSPData()) {
767 READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
768 READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
770 if (pps->pic_scaling_matrix_present_flag) {
771 DVLOG(4) <<
"Picture scaling matrix present";
772 res = ParsePPSScalingLists(br, *sps, pps.get());
777 READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
781 *pps_id = pps->pic_parameter_set_id;
782 delete active_PPSes_[*pps_id];
783 active_PPSes_[*pps_id] = pps.release();
788 H264Parser::Result H264Parser::ParseRefPicListModification(
790 int num_ref_idx_active_minus1,
791 H264ModificationOfPicNum* ref_list_mods) {
792 H264ModificationOfPicNum* pic_num_mod;
794 if (num_ref_idx_active_minus1 >= 32)
795 return kInvalidStream;
797 for (
int i = 0; i < 32; ++i) {
798 pic_num_mod = &ref_list_mods[i];
799 READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
800 TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
802 switch (pic_num_mod->modification_of_pic_nums_idc) {
805 READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
809 READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
815 return kInvalidStream;
819 return kInvalidStream;
825 int modification_of_pic_nums_idc;
826 READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
827 TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
832 H264Parser::Result H264Parser::ParseRefPicListModifications(
833 H264BitReader* br, H264SliceHeader* shdr) {
836 if (!shdr->IsISlice() && !shdr->IsSISlice()) {
837 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
838 if (shdr->ref_pic_list_modification_flag_l0) {
839 res = ParseRefPicListModification(br, shdr->num_ref_idx_l0_active_minus1,
840 shdr->ref_list_l0_modifications);
846 if (shdr->IsBSlice()) {
847 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
848 if (shdr->ref_pic_list_modification_flag_l1) {
849 res = ParseRefPicListModification(br, shdr->num_ref_idx_l1_active_minus1,
850 shdr->ref_list_l1_modifications);
859 H264Parser::Result H264Parser::ParseWeightingFactors(
861 int num_ref_idx_active_minus1,
862 int chroma_array_type,
863 int luma_log2_weight_denom,
864 int chroma_log2_weight_denom,
865 H264WeightingFactors* w_facts) {
866 int def_luma_weight = 1 << luma_log2_weight_denom;
867 int def_chroma_weight = 1 << chroma_log2_weight_denom;
869 for (
int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
870 READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag);
871 if (w_facts->luma_weight_flag) {
872 READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
873 IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
875 READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
876 IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
878 w_facts->luma_weight[i] = def_luma_weight;
879 w_facts->luma_offset[i] = 0;
882 if (chroma_array_type != 0) {
883 READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag);
884 if (w_facts->chroma_weight_flag) {
885 for (
int j = 0; j < 2; ++j) {
886 READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
887 IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
889 READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
890 IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
893 for (
int j = 0; j < 2; ++j) {
894 w_facts->chroma_weight[i][j] = def_chroma_weight;
895 w_facts->chroma_offset[i][j] = 0;
904 H264Parser::Result H264Parser::ParsePredWeightTable(H264BitReader* br,
906 H264SliceHeader* shdr) {
907 READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
908 TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
910 if (sps.chroma_array_type != 0)
911 READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
912 TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
914 Result res = ParseWeightingFactors(br,
915 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(br,
925 shdr->num_ref_idx_l1_active_minus1,
926 sps.chroma_array_type,
927 shdr->luma_log2_weight_denom,
928 shdr->chroma_log2_weight_denom,
929 &shdr->pred_weight_table_l1);
937 H264Parser::Result H264Parser::ParseDecRefPicMarking(H264BitReader* br,
938 H264SliceHeader* shdr) {
939 if (shdr->idr_pic_flag) {
940 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
941 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
943 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
945 H264DecRefPicMarking* marking;
946 if (shdr->adaptive_ref_pic_marking_mode_flag) {
948 for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) {
949 marking = &shdr->ref_pic_marking[i];
951 READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
952 if (marking->memory_mgmnt_control_operation == 0)
955 if (marking->memory_mgmnt_control_operation == 1 ||
956 marking->memory_mgmnt_control_operation == 3)
957 READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
959 if (marking->memory_mgmnt_control_operation == 2)
960 READ_UE_OR_RETURN(&marking->long_term_pic_num);
962 if (marking->memory_mgmnt_control_operation == 3 ||
963 marking->memory_mgmnt_control_operation == 6)
964 READ_UE_OR_RETURN(&marking->long_term_frame_idx);
966 if (marking->memory_mgmnt_control_operation == 4)
967 READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
969 if (marking->memory_mgmnt_control_operation > 6)
970 return kInvalidStream;
973 if (i == arraysize(shdr->ref_pic_marking)) {
974 DVLOG(1) <<
"Ran out of dec ref pic marking fields";
975 return kUnsupportedStream;
983 H264Parser::Result H264Parser::ParseSliceHeader(
const Nalu& nalu,
984 H264SliceHeader* shdr) {
989 H264BitReader reader;
990 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
991 H264BitReader* br = &reader;
993 memset(shdr, 0,
sizeof(*shdr));
995 shdr->idr_pic_flag = (nalu.type() == 5);
996 shdr->nal_ref_idc = nalu.ref_idc();
997 shdr->nalu_data = nalu.data() + nalu.header_size();
998 shdr->nalu_size = nalu.payload_size();
1000 READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
1001 READ_UE_OR_RETURN(&shdr->slice_type);
1002 TRUE_OR_RETURN(shdr->slice_type < 10);
1004 READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
1006 pps = GetPPS(shdr->pic_parameter_set_id);
1007 TRUE_OR_RETURN(pps);
1009 sps = GetSPS(pps->seq_parameter_set_id);
1010 TRUE_OR_RETURN(sps);
1012 if (sps->separate_colour_plane_flag) {
1013 DVLOG(1) <<
"Interlaced streams not supported";
1014 return kUnsupportedStream;
1017 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1018 if (!sps->frame_mbs_only_flag) {
1019 READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1020 if (shdr->field_pic_flag) {
1021 DVLOG(1) <<
"Interlaced streams not supported";
1022 return kUnsupportedStream;
1026 if (shdr->idr_pic_flag)
1027 READ_UE_OR_RETURN(&shdr->idr_pic_id);
1029 if (sps->pic_order_cnt_type == 0) {
1030 READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1031 &shdr->pic_order_cnt_lsb);
1032 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1033 !shdr->field_pic_flag)
1034 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1037 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1038 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[0]);
1039 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1040 !shdr->field_pic_flag)
1041 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[1]);
1044 if (pps->redundant_pic_cnt_present_flag) {
1045 READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1046 TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1049 if (shdr->IsBSlice())
1050 READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1052 if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1053 READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1054 if (shdr->num_ref_idx_active_override_flag) {
1055 READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1056 if (shdr->IsBSlice())
1057 READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1059 shdr->num_ref_idx_l0_active_minus1 =
1060 pps->num_ref_idx_l0_default_active_minus1;
1061 if (shdr->IsBSlice()) {
1062 shdr->num_ref_idx_l1_active_minus1 =
1063 pps->num_ref_idx_l1_default_active_minus1;
1067 if (shdr->field_pic_flag) {
1068 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1069 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1071 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1072 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1075 if (nalu.type() == Nalu::H264_CodedSliceExtension) {
1076 return kUnsupportedStream;
1078 res = ParseRefPicListModifications(br, shdr);
1083 if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1084 (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1085 res = ParsePredWeightTable(br, *sps, shdr);
1090 if (nalu.ref_idc() != 0) {
1091 res = ParseDecRefPicMarking(br, shdr);
1096 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1097 !shdr->IsSISlice()) {
1098 READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1099 TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1102 READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1104 if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1105 if (shdr->IsSPSlice())
1106 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1107 READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1110 if (pps->deblocking_filter_control_present_flag) {
1111 READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1112 TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1114 if (shdr->disable_deblocking_filter_idc != 1) {
1115 READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1116 IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1118 READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1119 IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1123 if (pps->num_slice_groups_minus1 > 0) {
1124 DVLOG(1) <<
"Slice groups not supported";
1125 return kUnsupportedStream;
1128 size_t epb = br->NumEmulationPreventionBytesRead();
1129 shdr->header_bit_size = (shdr->nalu_size - epb) * 8 - br->NumBitsLeft();
1134 H264Parser::Result H264Parser::ParseSEI(
const Nalu& nalu,
1135 H264SEIMessage* sei_msg) {
1137 H264BitReader reader;
1138 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
1139 H264BitReader* br = &reader;
1141 memset(sei_msg, 0,
sizeof(*sei_msg));
1143 READ_BITS_OR_RETURN(8, &byte);
1144 while (byte == 0xff) {
1145 sei_msg->type += 255;
1146 READ_BITS_OR_RETURN(8, &byte);
1148 sei_msg->type += byte;
1150 READ_BITS_OR_RETURN(8, &byte);
1151 while (byte == 0xff) {
1152 sei_msg->payload_size += 255;
1153 READ_BITS_OR_RETURN(8, &byte);
1155 sei_msg->payload_size += byte;
1157 DVLOG(4) <<
"Found SEI message type: " << sei_msg->type
1158 <<
" payload size: " << sei_msg->payload_size;
1160 switch (sei_msg->type) {
1161 case H264SEIMessage::kSEIRecoveryPoint:
1162 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1163 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1164 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1165 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1169 DVLOG(4) <<
"Unsupported SEI message";