5 #include "packager/media/codecs/h264_parser.h" 8 #include "packager/base/logging.h" 9 #include "packager/media/base/buffer_reader.h" 16 bool ExtractResolutionFromSps(
const H264Sps& sps,
17 uint32_t* coded_width,
18 uint32_t* coded_height,
19 uint32_t* pixel_width,
20 uint32_t* pixel_height) {
23 if (sps.frame_cropping_flag) {
27 switch (sps.chroma_format_idc) {
47 LOG(ERROR) <<
"Unexpected chroma_format_idc " << sps.chroma_format_idc;
52 int crop_unit_x = sub_width_c;
53 int crop_unit_y = sub_height_c * (2 - (sps.frame_mbs_only_flag ? 1 : 0));
54 crop_x = crop_unit_x *
55 (sps.frame_crop_left_offset + sps.frame_crop_right_offset);
56 crop_y = crop_unit_y *
57 (sps.frame_crop_top_offset + sps.frame_crop_bottom_offset);
61 int pic_width_in_mbs = sps.pic_width_in_mbs_minus1 + 1;
62 *coded_width = pic_width_in_mbs * 16 - crop_x;
65 int pic_height_in_mbs = (2 - (sps.frame_mbs_only_flag ? 1 : 0)) *
66 (sps.pic_height_in_map_units_minus1 + 1);
67 *coded_height = pic_height_in_mbs * 16 - crop_y;
70 *pixel_width = sps.sar_width == 0 ? 1 : sps.sar_width;
71 *pixel_height = sps.sar_height == 0 ? 1 : sps.sar_height;
72 DVLOG(2) <<
"Found coded_width: " << *coded_width
73 <<
" coded_height: " << *coded_height
74 <<
" pixel_width: " << *pixel_width
75 <<
" pixel_height: " << *pixel_height;
79 bool H264SliceHeader::IsPSlice()
const {
80 return (slice_type % 5 == kPSlice);
83 bool H264SliceHeader::IsBSlice()
const {
84 return (slice_type % 5 == kBSlice);
87 bool H264SliceHeader::IsISlice()
const {
88 return (slice_type % 5 == kISlice);
91 bool H264SliceHeader::IsSPSlice()
const {
92 return (slice_type % 5 == kSPSlice);
95 bool H264SliceHeader::IsSISlice()
const {
96 return (slice_type % 5 == kSISlice);
100 memset(
this, 0,
sizeof(*
this));
104 memset(
this, 0,
sizeof(*
this));
107 H264SliceHeader::H264SliceHeader() {
108 memset(
this, 0,
sizeof(*
this));
111 H264SEIMessage::H264SEIMessage() {
112 memset(
this, 0,
sizeof(*
this));
115 #define READ_BITS_OR_RETURN(num_bits, out) \ 117 if (!br->ReadBits(num_bits, (out))) { \ 119 << "Error in stream: unexpected EOS while trying to read " #out; \ 120 return kInvalidStream; \ 124 #define READ_BOOL_OR_RETURN(out) \ 127 if (!br->ReadBits(1, &_out)) { \ 129 << "Error in stream: unexpected EOS while trying to read " #out; \ 130 return kInvalidStream; \ 132 *(out) = _out != 0; \ 135 #define READ_UE_OR_RETURN(out) \ 137 if (!br->ReadUE(out)) { \ 138 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \ 139 return kInvalidStream; \ 143 #define READ_SE_OR_RETURN(out) \ 145 if (!br->ReadSE(out)) { \ 146 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \ 147 return kInvalidStream; \ 151 #define IN_RANGE_OR_RETURN(val, min, max) \ 153 if ((val) < (min) || (val) > (max)) { \ 154 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \ 155 << " in range [" << (min) << ":" << (max) << "]" \ 156 << " found " << (val) << " instead"; \ 157 return kInvalidStream; \ 161 #define TRUE_OR_RETURN(a) \ 164 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \ 165 return kInvalidStream; \ 169 enum AspectRatioIdc {
175 static const int kTableSarWidth[] = {
176 0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
178 static const int kTableSarHeight[] = {
179 0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
181 static_assert(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
182 "sar_tables_must_have_same_size");
184 H264Parser::H264Parser() {}
186 H264Parser::~H264Parser() {}
188 const H264Pps* H264Parser::GetPps(
int pps_id) {
189 return active_PPSes_[pps_id].get();
192 const H264Sps* H264Parser::GetSps(
int sps_id) {
193 return active_SPSes_[sps_id].get();
197 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
198 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
200 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
201 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
203 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
204 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
205 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
206 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
207 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
209 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
210 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
211 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
212 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
213 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
215 static inline void DefaultScalingList4x4(
217 int scaling_list4x4[][kH264ScalingList4x4Length]) {
221 memcpy(scaling_list4x4[i], kDefault4x4Intra,
sizeof(kDefault4x4Intra));
223 memcpy(scaling_list4x4[i], kDefault4x4Inter,
sizeof(kDefault4x4Inter));
226 static inline void DefaultScalingList8x8(
228 int scaling_list8x8[][kH264ScalingList8x8Length]) {
232 memcpy(scaling_list8x8[i], kDefault8x8Intra,
sizeof(kDefault8x8Intra));
234 memcpy(scaling_list8x8[i], kDefault8x8Inter,
sizeof(kDefault8x8Inter));
237 static void FallbackScalingList4x4(
239 const int default_scaling_list_intra[],
240 const int default_scaling_list_inter[],
241 int scaling_list4x4[][kH264ScalingList4x4Length]) {
242 static const int kScalingList4x4ByteSize =
243 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
247 memcpy(scaling_list4x4[i], default_scaling_list_intra,
248 kScalingList4x4ByteSize);
252 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
256 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
260 memcpy(scaling_list4x4[i], default_scaling_list_inter,
261 kScalingList4x4ByteSize);
265 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
269 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
278 static void FallbackScalingList8x8(
280 const int default_scaling_list_intra[],
281 const int default_scaling_list_inter[],
282 int scaling_list8x8[][kH264ScalingList8x8Length]) {
283 static const int kScalingList8x8ByteSize =
284 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
288 memcpy(scaling_list8x8[i], default_scaling_list_intra,
289 kScalingList8x8ByteSize);
293 memcpy(scaling_list8x8[i], default_scaling_list_inter,
294 kScalingList8x8ByteSize);
298 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
302 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
306 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
310 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
319 H264Parser::Result H264Parser::ParseScalingList(H26xBitReader* br,
328 *use_default =
false;
330 for (
int j = 0; j < size; ++j) {
331 if (next_scale != 0) {
332 READ_SE_OR_RETURN(&delta_scale);
333 IN_RANGE_OR_RETURN(delta_scale, -128, 127);
334 next_scale = (last_scale + delta_scale + 256) & 0xff;
336 if (j == 0 && next_scale == 0) {
342 scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
343 last_scale = scaling_list[j];
349 H264Parser::Result H264Parser::ParseSpsScalingLists(H26xBitReader* br,
352 bool seq_scaling_list_present_flag;
357 for (
int i = 0; i < 6; ++i) {
358 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
360 if (seq_scaling_list_present_flag) {
361 res = ParseScalingList(br,
362 arraysize(sps->scaling_list4x4[i]),
363 sps->scaling_list4x4[i],
369 DefaultScalingList4x4(i, sps->scaling_list4x4);
372 FallbackScalingList4x4(
373 i, kDefault4x4Intra, kDefault4x4Inter, sps->scaling_list4x4);
378 for (
int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
379 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
381 if (seq_scaling_list_present_flag) {
382 res = ParseScalingList(br,
383 arraysize(sps->scaling_list8x8[i]),
384 sps->scaling_list8x8[i],
390 DefaultScalingList8x8(i, sps->scaling_list8x8);
393 FallbackScalingList8x8(
394 i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8);
401 H264Parser::Result H264Parser::ParsePpsScalingLists(H26xBitReader* br,
405 bool pic_scaling_list_present_flag;
409 for (
int i = 0; i < 6; ++i) {
410 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
412 if (pic_scaling_list_present_flag) {
413 res = ParseScalingList(br,
414 arraysize(pps->scaling_list4x4[i]),
415 pps->scaling_list4x4[i],
421 DefaultScalingList4x4(i, pps->scaling_list4x4);
424 if (sps.seq_scaling_matrix_present_flag) {
426 FallbackScalingList4x4(
427 i, kDefault4x4Intra, kDefault4x4Inter, pps->scaling_list4x4);
430 FallbackScalingList4x4(i,
431 sps.scaling_list4x4[0],
432 sps.scaling_list4x4[3],
433 pps->scaling_list4x4);
438 if (pps->transform_8x8_mode_flag) {
439 for (
int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
440 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
442 if (pic_scaling_list_present_flag) {
443 res = ParseScalingList(br,
444 arraysize(pps->scaling_list8x8[i]),
445 pps->scaling_list8x8[i],
451 DefaultScalingList8x8(i, pps->scaling_list8x8);
454 if (sps.seq_scaling_matrix_present_flag) {
456 FallbackScalingList8x8(
457 i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8);
460 FallbackScalingList8x8(i,
461 sps.scaling_list8x8[0],
462 sps.scaling_list8x8[1],
463 pps->scaling_list8x8);
471 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
472 H26xBitReader* br,
bool* hrd_parameters_present) {
474 READ_BOOL_OR_RETURN(&data);
478 *hrd_parameters_present =
true;
481 READ_UE_OR_RETURN(&cpb_cnt_minus1);
482 IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
483 READ_BITS_OR_RETURN(8, &data);
484 for (
int i = 0; i <= cpb_cnt_minus1; ++i) {
485 READ_UE_OR_RETURN(&data);
486 READ_UE_OR_RETURN(&data);
487 READ_BOOL_OR_RETURN(&data);
489 READ_BITS_OR_RETURN(20, &data);
494 H264Parser::Result H264Parser::ParseVUIParameters(H26xBitReader* br,
496 bool aspect_ratio_info_present_flag;
497 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
498 if (aspect_ratio_info_present_flag) {
499 int aspect_ratio_idc;
500 READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
501 if (aspect_ratio_idc == kExtendedSar) {
502 READ_BITS_OR_RETURN(16, &sps->sar_width);
503 READ_BITS_OR_RETURN(16, &sps->sar_height);
505 const int max_aspect_ratio_idc = arraysize(kTableSarWidth) - 1;
506 IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
507 sps->sar_width = kTableSarWidth[aspect_ratio_idc];
508 sps->sar_height = kTableSarHeight[aspect_ratio_idc];
514 READ_BOOL_OR_RETURN(&data);
516 READ_BOOL_OR_RETURN(&data);
518 READ_BOOL_OR_RETURN(&data);
520 READ_BITS_OR_RETURN(3, &data);
521 READ_BOOL_OR_RETURN(&data);
522 READ_BOOL_OR_RETURN(&data);
524 READ_BITS_OR_RETURN(24, &data);
527 READ_BOOL_OR_RETURN(&data);
529 READ_UE_OR_RETURN(&data);
530 READ_UE_OR_RETURN(&data);
534 READ_BOOL_OR_RETURN(&data);
536 READ_BITS_OR_RETURN(16, &data);
537 READ_BITS_OR_RETURN(16, &data);
538 READ_BITS_OR_RETURN(16, &data);
539 READ_BITS_OR_RETURN(16, &data);
540 READ_BOOL_OR_RETURN(&data);
544 bool hrd_parameters_present =
false;
545 Result res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
550 res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
554 if (hrd_parameters_present)
555 READ_BOOL_OR_RETURN(&data);
557 READ_BOOL_OR_RETURN(&data);
558 READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
559 if (sps->bitstream_restriction_flag) {
560 READ_BOOL_OR_RETURN(&data);
561 READ_UE_OR_RETURN(&data);
562 READ_UE_OR_RETURN(&data);
563 READ_UE_OR_RETURN(&data);
564 READ_UE_OR_RETURN(&data);
565 READ_UE_OR_RETURN(&sps->max_num_reorder_frames);
566 READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
567 TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
569 sps->max_num_reorder_frames, 0, sps->max_dec_frame_buffering);
575 static void FillDefaultSeqScalingLists(H264Sps* sps) {
576 for (
int i = 0; i < 6; ++i)
577 for (
int j = 0; j < kH264ScalingList4x4Length; ++j)
578 sps->scaling_list4x4[i][j] = 16;
580 for (
int i = 0; i < 6; ++i)
581 for (
int j = 0; j < kH264ScalingList8x8Length; ++j)
582 sps->scaling_list8x8[i][j] = 16;
585 H264Parser::Result H264Parser::ParseSps(
const Nalu& nalu,
int* sps_id) {
589 H26xBitReader reader;
590 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
591 H26xBitReader* br = &reader;
595 std::unique_ptr<H264Sps> sps(
new H264Sps());
597 READ_BITS_OR_RETURN(8, &sps->profile_idc);
598 READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
599 READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
600 READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
601 READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
602 READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
603 READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
604 READ_BITS_OR_RETURN(2, &data);
605 READ_BITS_OR_RETURN(8, &sps->level_idc);
606 READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
607 TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
609 if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
610 sps->profile_idc == 122 || sps->profile_idc == 244 ||
611 sps->profile_idc == 44 || sps->profile_idc == 83 ||
612 sps->profile_idc == 86 || sps->profile_idc == 118 ||
613 sps->profile_idc == 128) {
614 READ_UE_OR_RETURN(&sps->chroma_format_idc);
615 TRUE_OR_RETURN(sps->chroma_format_idc < 4);
617 if (sps->chroma_format_idc == 3)
618 READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
620 READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
621 TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
623 READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
624 TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
626 READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
627 READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
629 if (sps->seq_scaling_matrix_present_flag) {
630 DVLOG(4) <<
"Scaling matrix present";
631 res = ParseSpsScalingLists(br, sps.get());
635 FillDefaultSeqScalingLists(sps.get());
638 sps->chroma_format_idc = 1;
639 FillDefaultSeqScalingLists(sps.get());
642 if (sps->separate_colour_plane_flag)
643 sps->chroma_array_type = 0;
645 sps->chroma_array_type = sps->chroma_format_idc;
647 READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
648 TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
650 READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
651 TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
653 sps->expected_delta_per_pic_order_cnt_cycle = 0;
654 if (sps->pic_order_cnt_type == 0) {
655 READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
656 TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
657 }
else if (sps->pic_order_cnt_type == 1) {
658 READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
659 READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
660 READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
661 READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
662 TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
664 for (
int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
665 READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
666 sps->expected_delta_per_pic_order_cnt_cycle +=
667 sps->offset_for_ref_frame[i];
671 READ_UE_OR_RETURN(&sps->max_num_ref_frames);
672 READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
674 READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
675 READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
677 READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
678 if (!sps->frame_mbs_only_flag)
679 READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
681 READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
683 READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
684 if (sps->frame_cropping_flag) {
685 READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
686 READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
687 READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
688 READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
691 READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
692 if (sps->vui_parameters_present_flag) {
693 DVLOG(4) <<
"VUI parameters present";
694 res = ParseVUIParameters(br, sps.get());
700 *sps_id = sps->seq_parameter_set_id;
701 active_SPSes_[*sps_id] = std::move(sps);
706 H264Parser::Result H264Parser::ParsePps(
const Nalu& nalu,
int* pps_id) {
710 H26xBitReader reader;
711 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
712 H26xBitReader* br = &reader;
716 std::unique_ptr<H264Pps> pps(
new H264Pps());
718 READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
719 READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
720 TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
722 sps = GetSps(pps->seq_parameter_set_id);
725 READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
726 READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
728 READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
729 if (pps->num_slice_groups_minus1 > 1) {
730 DVLOG(1) <<
"Slice groups not supported";
731 return kUnsupportedStream;
734 READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
735 TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
737 READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
738 TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
740 READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
741 READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
742 TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
744 READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
745 IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
747 READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
748 IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
750 READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
751 IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
752 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
754 READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
755 READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
756 READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
758 if (br->HasMoreRBSPData()) {
759 READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
760 READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
762 if (pps->pic_scaling_matrix_present_flag) {
763 DVLOG(4) <<
"Picture scaling matrix present";
764 res = ParsePpsScalingLists(br, *sps, pps.get());
769 READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
773 *pps_id = pps->pic_parameter_set_id;
774 active_PPSes_[*pps_id] = std::move(pps);
779 H264Parser::Result H264Parser::ParseRefPicListModification(
781 int num_ref_idx_active_minus1,
782 H264ModificationOfPicNum* ref_list_mods) {
783 H264ModificationOfPicNum* pic_num_mod;
785 if (num_ref_idx_active_minus1 >= 32)
786 return kInvalidStream;
788 for (
int i = 0; i < 32; ++i) {
789 pic_num_mod = &ref_list_mods[i];
790 READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
791 TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
793 switch (pic_num_mod->modification_of_pic_nums_idc) {
796 READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
800 READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
806 return kInvalidStream;
810 return kInvalidStream;
816 int modification_of_pic_nums_idc;
817 READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
818 TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
823 H264Parser::Result H264Parser::ParseRefPicListModifications(
824 H26xBitReader* br, H264SliceHeader* shdr) {
827 if (!shdr->IsISlice() && !shdr->IsSISlice()) {
828 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
829 if (shdr->ref_pic_list_modification_flag_l0) {
830 res = ParseRefPicListModification(br, shdr->num_ref_idx_l0_active_minus1,
831 shdr->ref_list_l0_modifications);
837 if (shdr->IsBSlice()) {
838 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
839 if (shdr->ref_pic_list_modification_flag_l1) {
840 res = ParseRefPicListModification(br, shdr->num_ref_idx_l1_active_minus1,
841 shdr->ref_list_l1_modifications);
850 H264Parser::Result H264Parser::ParseWeightingFactors(
852 int num_ref_idx_active_minus1,
853 int chroma_array_type,
854 int luma_log2_weight_denom,
855 int chroma_log2_weight_denom,
856 H264WeightingFactors* w_facts) {
857 int def_luma_weight = 1 << luma_log2_weight_denom;
858 int def_chroma_weight = 1 << chroma_log2_weight_denom;
860 for (
int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
861 READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag[i]);
862 if (w_facts->luma_weight_flag[i]) {
863 READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
864 IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
866 READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
867 IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
869 w_facts->luma_weight[i] = def_luma_weight;
870 w_facts->luma_offset[i] = 0;
873 if (chroma_array_type != 0) {
874 READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag[i]);
875 if (w_facts->chroma_weight_flag[i]) {
876 for (
int j = 0; j < 2; ++j) {
877 READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
878 IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
880 READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
881 IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
884 for (
int j = 0; j < 2; ++j) {
885 w_facts->chroma_weight[i][j] = def_chroma_weight;
886 w_facts->chroma_offset[i][j] = 0;
895 H264Parser::Result H264Parser::ParsePredWeightTable(H26xBitReader* br,
897 H264SliceHeader* shdr) {
898 READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
899 TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
901 if (sps.chroma_array_type != 0)
902 READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
903 TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
905 Result res = ParseWeightingFactors(br,
906 shdr->num_ref_idx_l0_active_minus1,
907 sps.chroma_array_type,
908 shdr->luma_log2_weight_denom,
909 shdr->chroma_log2_weight_denom,
910 &shdr->pred_weight_table_l0);
914 if (shdr->IsBSlice()) {
915 res = ParseWeightingFactors(br,
916 shdr->num_ref_idx_l1_active_minus1,
917 sps.chroma_array_type,
918 shdr->luma_log2_weight_denom,
919 shdr->chroma_log2_weight_denom,
920 &shdr->pred_weight_table_l1);
928 H264Parser::Result H264Parser::ParseDecRefPicMarking(H26xBitReader* br,
929 H264SliceHeader* shdr) {
930 if (shdr->idr_pic_flag) {
931 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
932 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
934 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
936 H264DecRefPicMarking* marking;
937 if (shdr->adaptive_ref_pic_marking_mode_flag) {
939 for (i = 0; i < arraysize(shdr->ref_pic_marking); ++i) {
940 marking = &shdr->ref_pic_marking[i];
942 READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
943 if (marking->memory_mgmnt_control_operation == 0)
946 if (marking->memory_mgmnt_control_operation == 1 ||
947 marking->memory_mgmnt_control_operation == 3)
948 READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
950 if (marking->memory_mgmnt_control_operation == 2)
951 READ_UE_OR_RETURN(&marking->long_term_pic_num);
953 if (marking->memory_mgmnt_control_operation == 3 ||
954 marking->memory_mgmnt_control_operation == 6)
955 READ_UE_OR_RETURN(&marking->long_term_frame_idx);
957 if (marking->memory_mgmnt_control_operation == 4)
958 READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
960 if (marking->memory_mgmnt_control_operation > 6)
961 return kInvalidStream;
964 if (i == arraysize(shdr->ref_pic_marking)) {
965 DVLOG(1) <<
"Ran out of dec ref pic marking fields";
966 return kUnsupportedStream;
974 H264Parser::Result H264Parser::ParseSliceHeader(
const Nalu& nalu,
975 H264SliceHeader* shdr) {
980 H26xBitReader reader;
981 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
982 H26xBitReader* br = &reader;
984 memset(shdr, 0,
sizeof(*shdr));
986 shdr->idr_pic_flag = (nalu.type() == 5);
987 shdr->nal_ref_idc = nalu.ref_idc();
988 shdr->nalu_data = nalu.data();
989 shdr->nalu_size = nalu.header_size() + nalu.payload_size();
991 READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
992 READ_UE_OR_RETURN(&shdr->slice_type);
993 TRUE_OR_RETURN(shdr->slice_type < 10);
995 READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
997 pps = GetPps(shdr->pic_parameter_set_id);
1000 sps = GetSps(pps->seq_parameter_set_id);
1001 TRUE_OR_RETURN(sps);
1003 if (sps->separate_colour_plane_flag) {
1004 DVLOG(1) <<
"Interlaced streams not supported";
1005 return kUnsupportedStream;
1008 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1009 if (!sps->frame_mbs_only_flag) {
1010 READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1011 if (shdr->field_pic_flag) {
1012 DVLOG(1) <<
"Interlaced streams not supported";
1013 return kUnsupportedStream;
1017 if (shdr->idr_pic_flag)
1018 READ_UE_OR_RETURN(&shdr->idr_pic_id);
1020 if (sps->pic_order_cnt_type == 0) {
1021 READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1022 &shdr->pic_order_cnt_lsb);
1023 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1024 !shdr->field_pic_flag)
1025 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1028 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1029 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[0]);
1030 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1031 !shdr->field_pic_flag)
1032 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[1]);
1035 if (pps->redundant_pic_cnt_present_flag) {
1036 READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1037 TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1040 if (shdr->IsBSlice())
1041 READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1043 if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1044 READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1045 if (shdr->num_ref_idx_active_override_flag) {
1046 READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1047 if (shdr->IsBSlice())
1048 READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1050 shdr->num_ref_idx_l0_active_minus1 =
1051 pps->num_ref_idx_l0_default_active_minus1;
1052 if (shdr->IsBSlice()) {
1053 shdr->num_ref_idx_l1_active_minus1 =
1054 pps->num_ref_idx_l1_default_active_minus1;
1058 if (shdr->field_pic_flag) {
1059 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1060 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1062 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1063 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1066 if (nalu.type() == Nalu::H264_CodedSliceExtension) {
1067 return kUnsupportedStream;
1069 res = ParseRefPicListModifications(br, shdr);
1074 if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1075 (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1076 res = ParsePredWeightTable(br, *sps, shdr);
1081 if (nalu.ref_idc() != 0) {
1082 res = ParseDecRefPicMarking(br, shdr);
1087 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1088 !shdr->IsSISlice()) {
1089 READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1090 TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1093 READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1095 if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1096 if (shdr->IsSPSlice())
1097 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1098 READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1101 if (pps->deblocking_filter_control_present_flag) {
1102 READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1103 TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1105 if (shdr->disable_deblocking_filter_idc != 1) {
1106 READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1107 IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1109 READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1110 IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1114 if (pps->num_slice_groups_minus1 > 0) {
1115 DVLOG(1) <<
"Slice groups not supported";
1116 return kUnsupportedStream;
1119 shdr->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
1123 H264Parser::Result H264Parser::ParseSEI(
const Nalu& nalu,
1124 H264SEIMessage* sei_msg) {
1126 H26xBitReader reader;
1127 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
1128 H26xBitReader* br = &reader;
1130 memset(sei_msg, 0,
sizeof(*sei_msg));
1132 READ_BITS_OR_RETURN(8, &byte);
1133 while (byte == 0xff) {
1134 sei_msg->type += 255;
1135 READ_BITS_OR_RETURN(8, &byte);
1137 sei_msg->type += byte;
1139 READ_BITS_OR_RETURN(8, &byte);
1140 while (byte == 0xff) {
1141 sei_msg->payload_size += 255;
1142 READ_BITS_OR_RETURN(8, &byte);
1144 sei_msg->payload_size += byte;
1146 DVLOG(4) <<
"Found SEI message type: " << sei_msg->type
1147 <<
" payload size: " << sei_msg->payload_size;
1149 switch (sei_msg->type) {
1150 case H264SEIMessage::kSEIRecoveryPoint:
1151 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1152 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1153 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1154 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1158 DVLOG(4) <<
"Unsupported SEI message";
All the methods that are virtual are virtual for mocking.