5 #include <packager/media/codecs/h264_parser.h>
9 #include <absl/log/check.h>
10 #include <absl/log/log.h>
12 #include <packager/macros/logging.h>
13 #include <packager/media/base/buffer_reader.h>
15 #define LOG_ERROR_ONCE(msg) \
17 static bool logged_once = false; \
18 LOG_IF(ERROR, !logged_once) << msg; \
27 bool ExtractResolutionFromSps(
const H264Sps& sps,
28 uint32_t* coded_width,
29 uint32_t* coded_height,
30 uint32_t* pixel_width,
31 uint32_t* pixel_height) {
34 if (sps.frame_cropping_flag) {
38 switch (sps.chroma_format_idc) {
58 LOG(ERROR) <<
"Unexpected chroma_format_idc " << sps.chroma_format_idc;
63 int crop_unit_x = sub_width_c;
64 int crop_unit_y = sub_height_c * (2 - (sps.frame_mbs_only_flag ? 1 : 0));
65 crop_x = crop_unit_x *
66 (sps.frame_crop_left_offset + sps.frame_crop_right_offset);
67 crop_y = crop_unit_y *
68 (sps.frame_crop_top_offset + sps.frame_crop_bottom_offset);
72 int pic_width_in_mbs = sps.pic_width_in_mbs_minus1 + 1;
73 *coded_width = pic_width_in_mbs * 16 - crop_x;
76 int pic_height_in_mbs = (2 - (sps.frame_mbs_only_flag ? 1 : 0)) *
77 (sps.pic_height_in_map_units_minus1 + 1);
78 *coded_height = pic_height_in_mbs * 16 - crop_y;
81 *pixel_width = sps.sar_width == 0 ? 1 : sps.sar_width;
82 *pixel_height = sps.sar_height == 0 ? 1 : sps.sar_height;
83 DVLOG(2) <<
"Found coded_width: " << *coded_width
84 <<
" coded_height: " << *coded_height
85 <<
" pixel_width: " << *pixel_width
86 <<
" pixel_height: " << *pixel_height;
90 bool H264SliceHeader::IsPSlice()
const {
91 return (slice_type % 5 == kPSlice);
94 bool H264SliceHeader::IsBSlice()
const {
95 return (slice_type % 5 == kBSlice);
98 bool H264SliceHeader::IsISlice()
const {
99 return (slice_type % 5 == kISlice);
102 bool H264SliceHeader::IsSPSlice()
const {
103 return (slice_type % 5 == kSPSlice);
106 bool H264SliceHeader::IsSISlice()
const {
107 return (slice_type % 5 == kSISlice);
110 #define READ_BITS_OR_RETURN(num_bits, out) \
112 if (!br->ReadBits(num_bits, (out))) { \
114 << "Error in stream: unexpected EOS while trying to read " #out; \
115 return kInvalidStream; \
119 #define READ_LONG_OR_RETURN(out) \
123 READ_BITS_OR_RETURN(16, &_tmp_out); \
124 _out = (long)(_tmp_out) << 16; \
125 READ_BITS_OR_RETURN(16, &_tmp_out); \
130 #define READ_BOOL_OR_RETURN(out) \
133 if (!br->ReadBits(1, &_out)) { \
135 << "Error in stream: unexpected EOS while trying to read " #out; \
136 return kInvalidStream; \
138 *(out) = _out != 0; \
141 #define READ_UE_OR_RETURN(out) \
143 if (!br->ReadUE(out)) { \
144 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
145 return kInvalidStream; \
149 #define READ_SE_OR_RETURN(out) \
151 if (!br->ReadSE(out)) { \
152 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
153 return kInvalidStream; \
157 #define IN_RANGE_OR_RETURN(val, min, max) \
159 if ((val) < (min) || (val) > (max)) { \
160 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
161 << " in range [" << (min) << ":" << (max) << "]" \
162 << " found " << (val) << " instead"; \
163 return kInvalidStream; \
167 #define TRUE_OR_RETURN(a) \
170 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
171 return kInvalidStream; \
175 enum AspectRatioIdc {
181 static const int kTableSarWidth[] = {
182 0, 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2
184 static const int kTableSarHeight[] = {
185 0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
187 static_assert(std::size(kTableSarWidth) == std::size(kTableSarHeight),
188 "sar_tables_must_have_same_size");
190 H264Parser::H264Parser() {}
192 H264Parser::~H264Parser() {}
194 const H264Pps* H264Parser::GetPps(
int pps_id) {
195 return active_PPSes_[pps_id].get();
198 const H264Sps* H264Parser::GetSps(
int sps_id) {
199 return active_SPSes_[sps_id].get();
203 static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
204 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42, };
206 static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
207 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34, };
209 static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
210 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
211 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
212 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
213 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42, };
215 static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
216 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
217 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
218 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
219 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35, };
221 static inline void DefaultScalingList4x4(
223 int scaling_list4x4[][kH264ScalingList4x4Length]) {
227 memcpy(scaling_list4x4[i], kDefault4x4Intra,
sizeof(kDefault4x4Intra));
229 memcpy(scaling_list4x4[i], kDefault4x4Inter,
sizeof(kDefault4x4Inter));
232 static inline void DefaultScalingList8x8(
234 int scaling_list8x8[][kH264ScalingList8x8Length]) {
238 memcpy(scaling_list8x8[i], kDefault8x8Intra,
sizeof(kDefault8x8Intra));
240 memcpy(scaling_list8x8[i], kDefault8x8Inter,
sizeof(kDefault8x8Inter));
243 static void FallbackScalingList4x4(
245 const int default_scaling_list_intra[],
246 const int default_scaling_list_inter[],
247 int scaling_list4x4[][kH264ScalingList4x4Length]) {
248 static const int kScalingList4x4ByteSize =
249 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
253 memcpy(scaling_list4x4[i], default_scaling_list_intra,
254 kScalingList4x4ByteSize);
258 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
262 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
266 memcpy(scaling_list4x4[i], default_scaling_list_inter,
267 kScalingList4x4ByteSize);
271 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
275 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
279 NOTIMPLEMENTED() <<
"index out of range [0,5]: " << i;
284 static void FallbackScalingList8x8(
286 const int default_scaling_list_intra[],
287 const int default_scaling_list_inter[],
288 int scaling_list8x8[][kH264ScalingList8x8Length]) {
289 static const int kScalingList8x8ByteSize =
290 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
294 memcpy(scaling_list8x8[i], default_scaling_list_intra,
295 kScalingList8x8ByteSize);
299 memcpy(scaling_list8x8[i], default_scaling_list_inter,
300 kScalingList8x8ByteSize);
304 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
308 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
312 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
316 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
320 NOTIMPLEMENTED() <<
"index out of range [0,5]: " << i;
325 H264Parser::Result H264Parser::ParseScalingList(H26xBitReader* br,
334 *use_default =
false;
336 for (
int j = 0; j < size; ++j) {
337 if (next_scale != 0) {
338 READ_SE_OR_RETURN(&delta_scale);
339 IN_RANGE_OR_RETURN(delta_scale, -128, 127);
340 next_scale = (last_scale + delta_scale + 256) & 0xff;
342 if (j == 0 && next_scale == 0) {
348 scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
349 last_scale = scaling_list[j];
355 H264Parser::Result H264Parser::ParseSpsScalingLists(H26xBitReader* br,
358 bool seq_scaling_list_present_flag;
363 for (
int i = 0; i < 6; ++i) {
364 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
366 if (seq_scaling_list_present_flag) {
367 res = ParseScalingList(br, std::size(sps->scaling_list4x4[i]),
368 sps->scaling_list4x4[i], &use_default);
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, std::size(sps->scaling_list8x8[i]),
387 sps->scaling_list8x8[i], &use_default);
392 DefaultScalingList8x8(i, sps->scaling_list8x8);
395 FallbackScalingList8x8(
396 i, kDefault8x8Intra, kDefault8x8Inter, sps->scaling_list8x8);
403 H264Parser::Result H264Parser::ParsePpsScalingLists(H26xBitReader* br,
407 bool pic_scaling_list_present_flag;
411 for (
int i = 0; i < 6; ++i) {
412 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
414 if (pic_scaling_list_present_flag) {
415 res = ParseScalingList(br, std::size(pps->scaling_list4x4[i]),
416 pps->scaling_list4x4[i], &use_default);
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, std::size(pps->scaling_list8x8[i]),
444 pps->scaling_list8x8[i], &use_default);
449 DefaultScalingList8x8(i, pps->scaling_list8x8);
452 if (sps.seq_scaling_matrix_present_flag) {
454 FallbackScalingList8x8(
455 i, kDefault8x8Intra, kDefault8x8Inter, pps->scaling_list8x8);
458 FallbackScalingList8x8(i,
459 sps.scaling_list8x8[0],
460 sps.scaling_list8x8[1],
461 pps->scaling_list8x8);
469 H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
470 H26xBitReader* br,
bool* hrd_parameters_present) {
472 READ_BOOL_OR_RETURN(&data);
476 *hrd_parameters_present =
true;
479 READ_UE_OR_RETURN(&cpb_cnt_minus1);
480 IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
481 READ_BITS_OR_RETURN(8, &data);
482 for (
int i = 0; i <= cpb_cnt_minus1; ++i) {
483 READ_UE_OR_RETURN(&data);
484 READ_UE_OR_RETURN(&data);
485 READ_BOOL_OR_RETURN(&data);
487 READ_BITS_OR_RETURN(20, &data);
492 H264Parser::Result H264Parser::ParseVUIParameters(H26xBitReader* br,
494 bool aspect_ratio_info_present_flag;
495 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
496 if (aspect_ratio_info_present_flag) {
497 int aspect_ratio_idc;
498 READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
499 if (aspect_ratio_idc == kExtendedSar) {
500 READ_BITS_OR_RETURN(16, &sps->sar_width);
501 READ_BITS_OR_RETURN(16, &sps->sar_height);
503 const int max_aspect_ratio_idc = std::size(kTableSarWidth) - 1;
504 IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
505 sps->sar_width = kTableSarWidth[aspect_ratio_idc];
506 sps->sar_height = kTableSarHeight[aspect_ratio_idc];
512 READ_BOOL_OR_RETURN(&data);
514 READ_BOOL_OR_RETURN(&data);
516 READ_BOOL_OR_RETURN(&data);
518 READ_BITS_OR_RETURN(3, &data);
519 READ_BOOL_OR_RETURN(&data);
520 READ_BOOL_OR_RETURN(&data);
522 READ_BITS_OR_RETURN(8, &sps->color_primaries);
523 READ_BITS_OR_RETURN(8, &sps->transfer_characteristics);
524 READ_BITS_OR_RETURN(8, &sps->matrix_coefficients);
528 READ_BOOL_OR_RETURN(&data);
530 READ_UE_OR_RETURN(&data);
531 READ_UE_OR_RETURN(&data);
535 READ_BOOL_OR_RETURN(&sps->timing_info_present_flag);
536 if (sps->timing_info_present_flag) {
537 READ_LONG_OR_RETURN(&sps->num_units_in_tick);
538 READ_LONG_OR_RETURN(&sps->time_scale);
539 READ_BOOL_OR_RETURN(&sps->fixed_frame_rate_flag);
543 bool hrd_parameters_present =
false;
544 Result res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
549 res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
553 if (hrd_parameters_present)
554 READ_BOOL_OR_RETURN(&data);
556 READ_BOOL_OR_RETURN(&data);
557 READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
558 if (sps->bitstream_restriction_flag) {
559 READ_BOOL_OR_RETURN(&data);
560 READ_UE_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(&sps->max_num_reorder_frames);
565 READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
566 TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
568 sps->max_num_reorder_frames, 0, sps->max_dec_frame_buffering);
574 static void FillDefaultSeqScalingLists(H264Sps* sps) {
575 for (
int i = 0; i < 6; ++i)
576 for (
int j = 0; j < kH264ScalingList4x4Length; ++j)
577 sps->scaling_list4x4[i][j] = 16;
579 for (
int i = 0; i < 6; ++i)
580 for (
int j = 0; j < kH264ScalingList8x8Length; ++j)
581 sps->scaling_list8x8[i][j] = 16;
584 H264Parser::Result H264Parser::ParseSps(
const Nalu& nalu,
int* sps_id) {
588 H26xBitReader reader;
589 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
590 H26xBitReader* br = &reader;
594 std::unique_ptr<H264Sps> sps(
new H264Sps());
596 READ_BITS_OR_RETURN(8, &sps->profile_idc);
597 READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
598 READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
599 READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
600 READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
601 READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
602 READ_BOOL_OR_RETURN(&sps->constraint_set5_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(br, 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 READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
674 READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
676 READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
677 if (!sps->frame_mbs_only_flag)
678 READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
680 READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
682 READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
683 if (sps->frame_cropping_flag) {
684 READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
685 READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
686 READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
687 READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
690 READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
691 if (sps->vui_parameters_present_flag) {
692 DVLOG(4) <<
"VUI parameters present";
693 res = ParseVUIParameters(br, sps.get());
699 *sps_id = sps->seq_parameter_set_id;
700 active_SPSes_[*sps_id] = std::move(sps);
705 H264Parser::Result H264Parser::ParsePps(
const Nalu& nalu,
int* pps_id) {
709 H26xBitReader reader;
710 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
711 H26xBitReader* br = &reader;
715 std::unique_ptr<H264Pps> pps(
new H264Pps());
717 READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
718 READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
719 TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
721 sps = GetSps(pps->seq_parameter_set_id);
724 READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
725 READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
727 READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
728 if (pps->num_slice_groups_minus1 > 1) {
729 LOG_ERROR_ONCE(
"Slice groups not supported");
730 return kUnsupportedStream;
733 READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
734 TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
736 READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
737 TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
739 READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
740 READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
741 TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
743 READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
744 IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
746 READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
747 IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
749 READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
750 IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
751 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
753 READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
754 READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
755 READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
757 if (br->HasMoreRBSPData()) {
758 READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
759 READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
761 if (pps->pic_scaling_matrix_present_flag) {
762 DVLOG(4) <<
"Picture scaling matrix present";
763 res = ParsePpsScalingLists(br, *sps, pps.get());
768 READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
772 *pps_id = pps->pic_parameter_set_id;
773 active_PPSes_[*pps_id] = std::move(pps);
778 H264Parser::Result H264Parser::ParseRefPicListModification(
780 int num_ref_idx_active_minus1,
781 H264ModificationOfPicNum* ref_list_mods) {
782 H264ModificationOfPicNum* pic_num_mod;
784 if (num_ref_idx_active_minus1 >= 32)
785 return kInvalidStream;
787 for (
int i = 0; i < 32; ++i) {
788 pic_num_mod = &ref_list_mods[i];
789 READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
790 TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
792 switch (pic_num_mod->modification_of_pic_nums_idc) {
795 READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
799 READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
805 return kInvalidStream;
809 return kInvalidStream;
815 int modification_of_pic_nums_idc;
816 READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
817 TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
822 H264Parser::Result H264Parser::ParseRefPicListModifications(
823 H26xBitReader* br, H264SliceHeader* shdr) {
826 if (!shdr->IsISlice() && !shdr->IsSISlice()) {
827 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
828 if (shdr->ref_pic_list_modification_flag_l0) {
829 res = ParseRefPicListModification(br, shdr->num_ref_idx_l0_active_minus1,
830 shdr->ref_list_l0_modifications);
836 if (shdr->IsBSlice()) {
837 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
838 if (shdr->ref_pic_list_modification_flag_l1) {
839 res = ParseRefPicListModification(br, shdr->num_ref_idx_l1_active_minus1,
840 shdr->ref_list_l1_modifications);
849 H264Parser::Result H264Parser::ParseWeightingFactors(
851 int num_ref_idx_active_minus1,
852 int chroma_array_type,
853 int luma_log2_weight_denom,
854 int chroma_log2_weight_denom,
855 H264WeightingFactors* w_facts) {
856 int def_luma_weight = 1 << luma_log2_weight_denom;
857 int def_chroma_weight = 1 << chroma_log2_weight_denom;
859 for (
int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
860 READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag[i]);
861 if (w_facts->luma_weight_flag[i]) {
862 READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
863 IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
865 READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
866 IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
868 w_facts->luma_weight[i] = def_luma_weight;
869 w_facts->luma_offset[i] = 0;
872 if (chroma_array_type != 0) {
873 READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag[i]);
874 if (w_facts->chroma_weight_flag[i]) {
875 for (
int j = 0; j < 2; ++j) {
876 READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
877 IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
879 READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
880 IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
883 for (
int j = 0; j < 2; ++j) {
884 w_facts->chroma_weight[i][j] = def_chroma_weight;
885 w_facts->chroma_offset[i][j] = 0;
894 H264Parser::Result H264Parser::ParsePredWeightTable(H26xBitReader* br,
896 H264SliceHeader* shdr) {
897 READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
898 TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
900 if (sps.chroma_array_type != 0)
901 READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
902 TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
904 Result res = ParseWeightingFactors(br,
905 shdr->num_ref_idx_l0_active_minus1,
906 sps.chroma_array_type,
907 shdr->luma_log2_weight_denom,
908 shdr->chroma_log2_weight_denom,
909 &shdr->pred_weight_table_l0);
913 if (shdr->IsBSlice()) {
914 res = ParseWeightingFactors(br,
915 shdr->num_ref_idx_l1_active_minus1,
916 sps.chroma_array_type,
917 shdr->luma_log2_weight_denom,
918 shdr->chroma_log2_weight_denom,
919 &shdr->pred_weight_table_l1);
927 H264Parser::Result H264Parser::ParseDecRefPicMarking(H26xBitReader* br,
928 H264SliceHeader* shdr) {
929 if (shdr->idr_pic_flag) {
930 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
931 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
933 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
935 H264DecRefPicMarking* marking;
936 if (shdr->adaptive_ref_pic_marking_mode_flag) {
938 for (i = 0; i < std::size(shdr->ref_pic_marking); ++i) {
939 marking = &shdr->ref_pic_marking[i];
941 READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
942 if (marking->memory_mgmnt_control_operation == 0)
945 if (marking->memory_mgmnt_control_operation == 1 ||
946 marking->memory_mgmnt_control_operation == 3)
947 READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
949 if (marking->memory_mgmnt_control_operation == 2)
950 READ_UE_OR_RETURN(&marking->long_term_pic_num);
952 if (marking->memory_mgmnt_control_operation == 3 ||
953 marking->memory_mgmnt_control_operation == 6)
954 READ_UE_OR_RETURN(&marking->long_term_frame_idx);
956 if (marking->memory_mgmnt_control_operation == 4)
957 READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
959 if (marking->memory_mgmnt_control_operation > 6)
960 return kInvalidStream;
963 if (i == std::size(shdr->ref_pic_marking)) {
964 LOG_ERROR_ONCE(
"Ran out of dec ref pic marking fields");
965 return kUnsupportedStream;
973 H264Parser::Result H264Parser::ParseSliceHeader(
const Nalu& nalu,
974 H264SliceHeader* shdr) {
979 H26xBitReader reader;
980 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
981 H26xBitReader* br = &reader;
985 shdr->idr_pic_flag = (nalu.type() == 5);
986 shdr->nal_ref_idc = nalu.ref_idc();
987 shdr->nalu_data = nalu.data();
988 shdr->nalu_size = nalu.header_size() + nalu.payload_size();
990 READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
991 READ_UE_OR_RETURN(&shdr->slice_type);
992 TRUE_OR_RETURN(shdr->slice_type < 10);
994 READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
996 pps = GetPps(shdr->pic_parameter_set_id);
999 sps = GetSps(pps->seq_parameter_set_id);
1000 TRUE_OR_RETURN(sps);
1002 if (sps->separate_colour_plane_flag) {
1003 LOG_ERROR_ONCE(
"Interlaced streams not supported");
1004 return kUnsupportedStream;
1007 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1008 if (!sps->frame_mbs_only_flag) {
1009 READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1010 if (shdr->field_pic_flag) {
1011 LOG_ERROR_ONCE(
"Interlaced streams not supported");
1012 return kUnsupportedStream;
1016 if (shdr->idr_pic_flag)
1017 READ_UE_OR_RETURN(&shdr->idr_pic_id);
1019 if (sps->pic_order_cnt_type == 0) {
1020 READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1021 &shdr->pic_order_cnt_lsb);
1022 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1023 !shdr->field_pic_flag)
1024 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1027 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1028 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[0]);
1029 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1030 !shdr->field_pic_flag)
1031 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[1]);
1034 if (pps->redundant_pic_cnt_present_flag) {
1035 READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1036 TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1039 if (shdr->IsBSlice())
1040 READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1042 if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1043 READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1044 if (shdr->num_ref_idx_active_override_flag) {
1045 READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1046 if (shdr->IsBSlice())
1047 READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1049 shdr->num_ref_idx_l0_active_minus1 =
1050 pps->num_ref_idx_l0_default_active_minus1;
1051 if (shdr->IsBSlice()) {
1052 shdr->num_ref_idx_l1_active_minus1 =
1053 pps->num_ref_idx_l1_default_active_minus1;
1057 if (shdr->field_pic_flag) {
1058 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1059 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1061 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1062 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1065 if (nalu.type() == Nalu::H264_CodedSliceExtension) {
1066 return kUnsupportedStream;
1068 res = ParseRefPicListModifications(br, shdr);
1073 if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1074 (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1075 res = ParsePredWeightTable(br, *sps, shdr);
1080 if (nalu.ref_idc() != 0) {
1081 res = ParseDecRefPicMarking(br, shdr);
1086 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1087 !shdr->IsSISlice()) {
1088 READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1089 TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1092 READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1094 if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1095 if (shdr->IsSPSlice())
1096 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1097 READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1100 if (pps->deblocking_filter_control_present_flag) {
1101 READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1102 TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1104 if (shdr->disable_deblocking_filter_idc != 1) {
1105 READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1106 IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1108 READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1109 IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1113 if (pps->num_slice_groups_minus1 > 0) {
1114 LOG_ERROR_ONCE(
"Slice groups not supported");
1115 return kUnsupportedStream;
1118 shdr->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
1122 H264Parser::Result H264Parser::ParseSEI(
const Nalu& nalu,
1123 H264SEIMessage* sei_msg) {
1125 H26xBitReader reader;
1126 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
1127 H26xBitReader* br = &reader;
1131 READ_BITS_OR_RETURN(8, &
byte);
1132 while (
byte == 0xff) {
1133 sei_msg->type += 255;
1134 READ_BITS_OR_RETURN(8, &
byte);
1136 sei_msg->type += byte;
1138 READ_BITS_OR_RETURN(8, &
byte);
1139 while (
byte == 0xff) {
1140 sei_msg->payload_size += 255;
1141 READ_BITS_OR_RETURN(8, &
byte);
1143 sei_msg->payload_size += byte;
1145 DVLOG(4) <<
"Found SEI message type: " << sei_msg->type
1146 <<
" payload size: " << sei_msg->payload_size;
1148 switch (sei_msg->type) {
1149 case H264SEIMessage::kSEIRecoveryPoint:
1150 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1151 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1152 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1153 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1157 DVLOG(4) <<
"Unsupported SEI message";
All the methods that are virtual are virtual for mocking.