5#include <packager/media/codecs/h264_parser.h>
14#include <absl/log/check.h>
15#include <absl/log/log.h>
17#include <packager/macros/logging.h>
18#include <packager/media/codecs/h26x_bit_reader.h>
19#include <packager/media/codecs/nalu_reader.h>
21#define LOG_ERROR_ONCE(msg) \
23 static bool logged_once = false; \
24 LOG_IF(ERROR, !logged_once) << msg; \
33bool ExtractResolutionFromSps(
const H264Sps& sps,
34 uint32_t* coded_width,
35 uint32_t* coded_height,
36 uint32_t* pixel_width,
37 uint32_t* pixel_height) {
40 if (sps.frame_cropping_flag) {
44 switch (sps.chroma_format_idc) {
64 LOG(ERROR) <<
"Unexpected chroma_format_idc " << sps.chroma_format_idc;
69 int crop_unit_x = sub_width_c;
70 int crop_unit_y = sub_height_c * (2 - (sps.frame_mbs_only_flag ? 1 : 0));
71 crop_x = crop_unit_x *
72 (sps.frame_crop_left_offset + sps.frame_crop_right_offset);
73 crop_y = crop_unit_y *
74 (sps.frame_crop_top_offset + sps.frame_crop_bottom_offset);
78 int pic_width_in_mbs = sps.pic_width_in_mbs_minus1 + 1;
79 *coded_width = pic_width_in_mbs * 16 - crop_x;
82 int pic_height_in_mbs = (2 - (sps.frame_mbs_only_flag ? 1 : 0)) *
83 (sps.pic_height_in_map_units_minus1 + 1);
84 *coded_height = pic_height_in_mbs * 16 - crop_y;
87 *pixel_width = sps.sar_width == 0 ? 1 : sps.sar_width;
88 *pixel_height = sps.sar_height == 0 ? 1 : sps.sar_height;
89 DVLOG(2) <<
"Found coded_width: " << *coded_width
90 <<
" coded_height: " << *coded_height
91 <<
" pixel_width: " << *pixel_width
92 <<
" pixel_height: " << *pixel_height;
96bool H264SliceHeader::IsPSlice()
const {
97 return (slice_type % 5 == kPSlice);
100bool H264SliceHeader::IsBSlice()
const {
101 return (slice_type % 5 == kBSlice);
104bool H264SliceHeader::IsISlice()
const {
105 return (slice_type % 5 == kISlice);
108bool H264SliceHeader::IsSPSlice()
const {
109 return (slice_type % 5 == kSPSlice);
112bool H264SliceHeader::IsSISlice()
const {
113 return (slice_type % 5 == kSISlice);
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_LONG_OR_RETURN(out) \
129 READ_BITS_OR_RETURN(16, &_tmp_out); \
130 _out = (long)(_tmp_out) << 16; \
131 READ_BITS_OR_RETURN(16, &_tmp_out); \
136#define READ_BOOL_OR_RETURN(out) \
139 if (!br->ReadBits(1, &_out)) { \
141 << "Error in stream: unexpected EOS while trying to read " #out; \
142 return kInvalidStream; \
144 *(out) = _out != 0; \
147#define READ_UE_OR_RETURN(out) \
149 if (!br->ReadUE(out)) { \
150 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
151 return kInvalidStream; \
155#define READ_SE_OR_RETURN(out) \
157 if (!br->ReadSE(out)) { \
158 DVLOG(1) << "Error in stream: invalid value while trying to read " #out; \
159 return kInvalidStream; \
163#define IN_RANGE_OR_RETURN(val, min, max) \
165 if ((val) < (min) || (val) > (max)) { \
166 DVLOG(1) << "Error in stream: invalid value, expected " #val " to be" \
167 << " in range [" << (min) << ":" << (max) << "]" \
168 << " found " << (val) << " instead"; \
169 return kInvalidStream; \
173#define TRUE_OR_RETURN(a) \
176 DVLOG(1) << "Error in stream: invalid value, expected " << #a; \
177 return kInvalidStream; \
187static const int kTableSarWidth[] = {0, 1, 12, 10, 16, 40, 24, 20, 32,
188 80, 18, 15, 64, 160, 4, 3, 2};
189static const int kTableSarHeight[] = {0, 1, 11, 11, 11, 33, 11, 11, 11,
190 33, 11, 11, 33, 99, 3, 2, 1};
191static_assert(std::size(kTableSarWidth) == std::size(kTableSarHeight),
192 "sar_tables_must_have_same_size");
194H264Parser::H264Parser() {}
196H264Parser::~H264Parser() {}
198const H264Pps* H264Parser::GetPps(
int pps_id) {
199 return active_PPSes_[pps_id].get();
202const H264Sps* H264Parser::GetSps(
int sps_id) {
203 return active_SPSes_[sps_id].get();
207static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
208 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42,
211static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
212 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34,
215static const int kDefault8x8Intra[kH264ScalingList8x8Length] = {
216 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23,
217 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27,
218 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31,
219 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42,
222static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
223 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
224 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
225 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
226 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
229static inline void DefaultScalingList4x4(
231 int scaling_list4x4[][kH264ScalingList4x4Length]) {
235 memcpy(scaling_list4x4[i], kDefault4x4Intra,
sizeof(kDefault4x4Intra));
237 memcpy(scaling_list4x4[i], kDefault4x4Inter,
sizeof(kDefault4x4Inter));
240static inline void DefaultScalingList8x8(
242 int scaling_list8x8[][kH264ScalingList8x8Length]) {
246 memcpy(scaling_list8x8[i], kDefault8x8Intra,
sizeof(kDefault8x8Intra));
248 memcpy(scaling_list8x8[i], kDefault8x8Inter,
sizeof(kDefault8x8Inter));
251static void FallbackScalingList4x4(
253 const int default_scaling_list_intra[],
254 const int default_scaling_list_inter[],
255 int scaling_list4x4[][kH264ScalingList4x4Length]) {
256 static const int kScalingList4x4ByteSize =
257 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
261 memcpy(scaling_list4x4[i], default_scaling_list_intra,
262 kScalingList4x4ByteSize);
266 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
270 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
274 memcpy(scaling_list4x4[i], default_scaling_list_inter,
275 kScalingList4x4ByteSize);
279 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
283 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
287 NOTIMPLEMENTED() <<
"index out of range [0,5]: " << i;
292static void FallbackScalingList8x8(
294 const int default_scaling_list_intra[],
295 const int default_scaling_list_inter[],
296 int scaling_list8x8[][kH264ScalingList8x8Length]) {
297 static const int kScalingList8x8ByteSize =
298 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
302 memcpy(scaling_list8x8[i], default_scaling_list_intra,
303 kScalingList8x8ByteSize);
307 memcpy(scaling_list8x8[i], default_scaling_list_inter,
308 kScalingList8x8ByteSize);
312 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
316 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
320 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
324 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
328 NOTIMPLEMENTED() <<
"index out of range [0,5]: " << i;
333H264Parser::Result H264Parser::ParseScalingList(H26xBitReader* br,
342 *use_default =
false;
344 for (
int j = 0; j < size; ++j) {
345 if (next_scale != 0) {
346 READ_SE_OR_RETURN(&delta_scale);
347 IN_RANGE_OR_RETURN(delta_scale, -128, 127);
348 next_scale = (last_scale + delta_scale + 256) & 0xff;
350 if (j == 0 && next_scale == 0) {
356 scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
357 last_scale = scaling_list[j];
363H264Parser::Result H264Parser::ParseSpsScalingLists(H26xBitReader* br,
366 bool seq_scaling_list_present_flag;
371 for (
int i = 0; i < 6; ++i) {
372 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
374 if (seq_scaling_list_present_flag) {
375 res = ParseScalingList(br, std::size(sps->scaling_list4x4[i]),
376 sps->scaling_list4x4[i], &use_default);
381 DefaultScalingList4x4(i, sps->scaling_list4x4);
384 FallbackScalingList4x4(i, kDefault4x4Intra, kDefault4x4Inter,
385 sps->scaling_list4x4);
390 for (
int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
391 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
393 if (seq_scaling_list_present_flag) {
394 res = ParseScalingList(br, std::size(sps->scaling_list8x8[i]),
395 sps->scaling_list8x8[i], &use_default);
400 DefaultScalingList8x8(i, sps->scaling_list8x8);
403 FallbackScalingList8x8(i, kDefault8x8Intra, kDefault8x8Inter,
404 sps->scaling_list8x8);
411H264Parser::Result H264Parser::ParsePpsScalingLists(H26xBitReader* br,
415 bool pic_scaling_list_present_flag;
419 for (
int i = 0; i < 6; ++i) {
420 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
422 if (pic_scaling_list_present_flag) {
423 res = ParseScalingList(br, std::size(pps->scaling_list4x4[i]),
424 pps->scaling_list4x4[i], &use_default);
429 DefaultScalingList4x4(i, pps->scaling_list4x4);
432 if (sps.seq_scaling_matrix_present_flag) {
434 FallbackScalingList4x4(i, kDefault4x4Intra, kDefault4x4Inter,
435 pps->scaling_list4x4);
438 FallbackScalingList4x4(i, sps.scaling_list4x4[0],
439 sps.scaling_list4x4[3], pps->scaling_list4x4);
444 if (pps->transform_8x8_mode_flag) {
445 for (
int i = 0; i < ((sps.chroma_format_idc != 3) ? 2 : 6); ++i) {
446 READ_BOOL_OR_RETURN(&pic_scaling_list_present_flag);
448 if (pic_scaling_list_present_flag) {
449 res = ParseScalingList(br, std::size(pps->scaling_list8x8[i]),
450 pps->scaling_list8x8[i], &use_default);
455 DefaultScalingList8x8(i, pps->scaling_list8x8);
458 if (sps.seq_scaling_matrix_present_flag) {
460 FallbackScalingList8x8(i, kDefault8x8Intra, kDefault8x8Inter,
461 pps->scaling_list8x8);
464 FallbackScalingList8x8(i, sps.scaling_list8x8[0],
465 sps.scaling_list8x8[1], pps->scaling_list8x8);
473H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
475 bool* hrd_parameters_present) {
477 READ_BOOL_OR_RETURN(&data);
481 *hrd_parameters_present =
true;
484 READ_UE_OR_RETURN(&cpb_cnt_minus1);
485 IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
486 READ_BITS_OR_RETURN(8, &data);
487 for (
int i = 0; i <= cpb_cnt_minus1; ++i) {
488 READ_UE_OR_RETURN(&data);
489 READ_UE_OR_RETURN(&data);
490 READ_BOOL_OR_RETURN(&data);
492 READ_BITS_OR_RETURN(20, &data);
497H264Parser::Result H264Parser::ParseVUIParameters(H26xBitReader* br,
499 bool aspect_ratio_info_present_flag;
500 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
501 if (aspect_ratio_info_present_flag) {
502 int aspect_ratio_idc;
503 READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
504 if (aspect_ratio_idc == kExtendedSar) {
505 READ_BITS_OR_RETURN(16, &sps->sar_width);
506 READ_BITS_OR_RETURN(16, &sps->sar_height);
508 const int max_aspect_ratio_idc = std::size(kTableSarWidth) - 1;
509 IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
510 sps->sar_width = kTableSarWidth[aspect_ratio_idc];
511 sps->sar_height = kTableSarHeight[aspect_ratio_idc];
517 READ_BOOL_OR_RETURN(&data);
519 READ_BOOL_OR_RETURN(&data);
521 READ_BOOL_OR_RETURN(&data);
523 READ_BITS_OR_RETURN(3, &data);
524 READ_BOOL_OR_RETURN(&data);
525 READ_BOOL_OR_RETURN(&data);
527 READ_BITS_OR_RETURN(8, &sps->color_primaries);
528 READ_BITS_OR_RETURN(8, &sps->transfer_characteristics);
529 READ_BITS_OR_RETURN(8, &sps->matrix_coefficients);
533 READ_BOOL_OR_RETURN(&data);
535 READ_UE_OR_RETURN(&data);
536 READ_UE_OR_RETURN(&data);
540 READ_BOOL_OR_RETURN(&sps->timing_info_present_flag);
541 if (sps->timing_info_present_flag) {
542 READ_LONG_OR_RETURN(&sps->num_units_in_tick);
543 READ_LONG_OR_RETURN(&sps->time_scale);
544 READ_BOOL_OR_RETURN(&sps->fixed_frame_rate_flag);
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);
572 IN_RANGE_OR_RETURN(sps->max_num_reorder_frames, 0,
573 sps->max_dec_frame_buffering);
579static 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;
589H264Parser::Result H264Parser::ParseSps(
const Nalu& nalu,
int* sps_id) {
593 H26xBitReader reader;
594 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
595 H26xBitReader* br = &reader;
599 std::unique_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 READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
679 READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
681 READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
682 if (!sps->frame_mbs_only_flag)
683 READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
685 READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
687 READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
688 if (sps->frame_cropping_flag) {
689 READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
690 READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
691 READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
692 READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
695 READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
696 if (sps->vui_parameters_present_flag) {
697 DVLOG(4) <<
"VUI parameters present";
698 res = ParseVUIParameters(br, sps.get());
704 *sps_id = sps->seq_parameter_set_id;
705 active_SPSes_[*sps_id] = std::move(sps);
710H264Parser::Result H264Parser::ParsePps(
const Nalu& nalu,
int* pps_id) {
714 H26xBitReader reader;
715 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
716 H26xBitReader* br = &reader;
720 std::unique_ptr<H264Pps> pps(
new H264Pps());
722 READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
723 READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
724 TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
726 sps = GetSps(pps->seq_parameter_set_id);
729 READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
730 READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
732 READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
733 if (pps->num_slice_groups_minus1 > 1) {
734 LOG_ERROR_ONCE(
"Slice groups not supported");
735 return kUnsupportedStream;
738 READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
739 TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
741 READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
742 TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
744 READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
745 READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
746 TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
748 READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
749 IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
751 READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
752 IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
754 READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
755 IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
756 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
758 READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
759 READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
760 READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
762 if (br->HasMoreRBSPData()) {
763 READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
764 READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
766 if (pps->pic_scaling_matrix_present_flag) {
767 DVLOG(4) <<
"Picture scaling matrix present";
768 res = ParsePpsScalingLists(br, *sps, pps.get());
773 READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
777 *pps_id = pps->pic_parameter_set_id;
778 active_PPSes_[*pps_id] = std::move(pps);
783H264Parser::Result H264Parser::ParseRefPicListModification(
785 int num_ref_idx_active_minus1,
786 H264ModificationOfPicNum* ref_list_mods) {
787 H264ModificationOfPicNum* pic_num_mod;
789 if (num_ref_idx_active_minus1 >= 32)
790 return kInvalidStream;
792 for (
int i = 0; i < 32; ++i) {
793 pic_num_mod = &ref_list_mods[i];
794 READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
795 TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
797 switch (pic_num_mod->modification_of_pic_nums_idc) {
800 READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
804 READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
810 return kInvalidStream;
814 return kInvalidStream;
820 int modification_of_pic_nums_idc;
821 READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
822 TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
827H264Parser::Result H264Parser::ParseRefPicListModifications(
829 H264SliceHeader* shdr) {
832 if (!shdr->IsISlice() && !shdr->IsSISlice()) {
833 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l0);
834 if (shdr->ref_pic_list_modification_flag_l0) {
835 res = ParseRefPicListModification(br, shdr->num_ref_idx_l0_active_minus1,
836 shdr->ref_list_l0_modifications);
842 if (shdr->IsBSlice()) {
843 READ_BOOL_OR_RETURN(&shdr->ref_pic_list_modification_flag_l1);
844 if (shdr->ref_pic_list_modification_flag_l1) {
845 res = ParseRefPicListModification(br, shdr->num_ref_idx_l1_active_minus1,
846 shdr->ref_list_l1_modifications);
855H264Parser::Result H264Parser::ParseWeightingFactors(
857 int num_ref_idx_active_minus1,
858 int chroma_array_type,
859 int luma_log2_weight_denom,
860 int chroma_log2_weight_denom,
861 H264WeightingFactors* w_facts) {
862 int def_luma_weight = 1 << luma_log2_weight_denom;
863 int def_chroma_weight = 1 << chroma_log2_weight_denom;
865 for (
int i = 0; i < num_ref_idx_active_minus1 + 1; ++i) {
866 READ_BOOL_OR_RETURN(&w_facts->luma_weight_flag[i]);
867 if (w_facts->luma_weight_flag[i]) {
868 READ_SE_OR_RETURN(&w_facts->luma_weight[i]);
869 IN_RANGE_OR_RETURN(w_facts->luma_weight[i], -128, 127);
871 READ_SE_OR_RETURN(&w_facts->luma_offset[i]);
872 IN_RANGE_OR_RETURN(w_facts->luma_offset[i], -128, 127);
874 w_facts->luma_weight[i] = def_luma_weight;
875 w_facts->luma_offset[i] = 0;
878 if (chroma_array_type != 0) {
879 READ_BOOL_OR_RETURN(&w_facts->chroma_weight_flag[i]);
880 if (w_facts->chroma_weight_flag[i]) {
881 for (
int j = 0; j < 2; ++j) {
882 READ_SE_OR_RETURN(&w_facts->chroma_weight[i][j]);
883 IN_RANGE_OR_RETURN(w_facts->chroma_weight[i][j], -128, 127);
885 READ_SE_OR_RETURN(&w_facts->chroma_offset[i][j]);
886 IN_RANGE_OR_RETURN(w_facts->chroma_offset[i][j], -128, 127);
889 for (
int j = 0; j < 2; ++j) {
890 w_facts->chroma_weight[i][j] = def_chroma_weight;
891 w_facts->chroma_offset[i][j] = 0;
900H264Parser::Result H264Parser::ParsePredWeightTable(H26xBitReader* br,
902 H264SliceHeader* shdr) {
903 READ_UE_OR_RETURN(&shdr->luma_log2_weight_denom);
904 TRUE_OR_RETURN(shdr->luma_log2_weight_denom < 8);
906 if (sps.chroma_array_type != 0)
907 READ_UE_OR_RETURN(&shdr->chroma_log2_weight_denom);
908 TRUE_OR_RETURN(shdr->chroma_log2_weight_denom < 8);
910 Result res = ParseWeightingFactors(
911 br, shdr->num_ref_idx_l0_active_minus1, sps.chroma_array_type,
912 shdr->luma_log2_weight_denom, shdr->chroma_log2_weight_denom,
913 &shdr->pred_weight_table_l0);
917 if (shdr->IsBSlice()) {
918 res = ParseWeightingFactors(
919 br, shdr->num_ref_idx_l1_active_minus1, sps.chroma_array_type,
920 shdr->luma_log2_weight_denom, shdr->chroma_log2_weight_denom,
921 &shdr->pred_weight_table_l1);
929H264Parser::Result H264Parser::ParseDecRefPicMarking(H26xBitReader* br,
930 H264SliceHeader* shdr) {
931 if (shdr->idr_pic_flag) {
932 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
933 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
935 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
937 H264DecRefPicMarking* marking;
938 if (shdr->adaptive_ref_pic_marking_mode_flag) {
940 for (i = 0; i < std::size(shdr->ref_pic_marking); ++i) {
941 marking = &shdr->ref_pic_marking[i];
943 READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
944 if (marking->memory_mgmnt_control_operation == 0)
947 if (marking->memory_mgmnt_control_operation == 1 ||
948 marking->memory_mgmnt_control_operation == 3)
949 READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
951 if (marking->memory_mgmnt_control_operation == 2)
952 READ_UE_OR_RETURN(&marking->long_term_pic_num);
954 if (marking->memory_mgmnt_control_operation == 3 ||
955 marking->memory_mgmnt_control_operation == 6)
956 READ_UE_OR_RETURN(&marking->long_term_frame_idx);
958 if (marking->memory_mgmnt_control_operation == 4)
959 READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
961 if (marking->memory_mgmnt_control_operation > 6)
962 return kInvalidStream;
965 if (i == std::size(shdr->ref_pic_marking)) {
966 LOG_ERROR_ONCE(
"Ran out of dec ref pic marking fields");
967 return kUnsupportedStream;
975H264Parser::Result H264Parser::ParseSliceHeader(
const Nalu& nalu,
976 H264SliceHeader* shdr) {
981 H26xBitReader reader;
982 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
983 H26xBitReader* br = &reader;
987 shdr->idr_pic_flag = (nalu.type() == 5);
988 shdr->nal_ref_idc = nalu.ref_idc();
989 shdr->nalu_data = nalu.data();
990 shdr->nalu_size = nalu.header_size() + nalu.payload_size();
992 READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
993 READ_UE_OR_RETURN(&shdr->slice_type);
994 TRUE_OR_RETURN(shdr->slice_type < 10);
996 READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
998 pps = GetPps(shdr->pic_parameter_set_id);
1001 sps = GetSps(pps->seq_parameter_set_id);
1002 TRUE_OR_RETURN(sps);
1004 if (sps->separate_colour_plane_flag) {
1005 LOG_ERROR_ONCE(
"Interlaced streams not supported");
1006 return kUnsupportedStream;
1009 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1010 if (!sps->frame_mbs_only_flag) {
1011 READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1012 if (shdr->field_pic_flag) {
1013 LOG_ERROR_ONCE(
"Interlaced streams not supported");
1014 return kUnsupportedStream;
1018 if (shdr->idr_pic_flag)
1019 READ_UE_OR_RETURN(&shdr->idr_pic_id);
1021 if (sps->pic_order_cnt_type == 0) {
1022 READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1023 &shdr->pic_order_cnt_lsb);
1024 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1025 !shdr->field_pic_flag)
1026 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1029 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1030 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[0]);
1031 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1032 !shdr->field_pic_flag)
1033 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[1]);
1036 if (pps->redundant_pic_cnt_present_flag) {
1037 READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1038 TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1041 if (shdr->IsBSlice())
1042 READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1044 if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1045 READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1046 if (shdr->num_ref_idx_active_override_flag) {
1047 READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1048 if (shdr->IsBSlice())
1049 READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1051 shdr->num_ref_idx_l0_active_minus1 =
1052 pps->num_ref_idx_l0_default_active_minus1;
1053 if (shdr->IsBSlice()) {
1054 shdr->num_ref_idx_l1_active_minus1 =
1055 pps->num_ref_idx_l1_default_active_minus1;
1059 if (shdr->field_pic_flag) {
1060 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1061 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1063 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1064 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1067 if (nalu.type() == Nalu::H264_CodedSliceExtension) {
1068 return kUnsupportedStream;
1070 res = ParseRefPicListModifications(br, shdr);
1075 if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1076 (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1077 res = ParsePredWeightTable(br, *sps, shdr);
1082 if (nalu.ref_idc() != 0) {
1083 res = ParseDecRefPicMarking(br, shdr);
1088 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1089 !shdr->IsSISlice()) {
1090 READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1091 TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1094 READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1096 if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1097 if (shdr->IsSPSlice())
1098 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1099 READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1102 if (pps->deblocking_filter_control_present_flag) {
1103 READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1104 TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1106 if (shdr->disable_deblocking_filter_idc != 1) {
1107 READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1108 IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1110 READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1111 IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1115 if (pps->num_slice_groups_minus1 > 0) {
1116 LOG_ERROR_ONCE(
"Slice groups not supported");
1117 return kUnsupportedStream;
1120 shdr->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
1124H264Parser::Result H264Parser::ParseSEI(
const Nalu& nalu,
1125 H264SEIMessage* sei_msg) {
1127 H26xBitReader reader;
1128 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
1129 H26xBitReader* br = &reader;
1133 READ_BITS_OR_RETURN(8, &
byte);
1134 while (
byte == 0xff) {
1135 sei_msg->type += 255;
1136 READ_BITS_OR_RETURN(8, &
byte);
1138 sei_msg->type += byte;
1140 READ_BITS_OR_RETURN(8, &
byte);
1141 while (
byte == 0xff) {
1142 sei_msg->payload_size += 255;
1143 READ_BITS_OR_RETURN(8, &
byte);
1145 sei_msg->payload_size += byte;
1147 DVLOG(4) <<
"Found SEI message type: " << sei_msg->type
1148 <<
" payload size: " << sei_msg->payload_size;
1150 switch (sei_msg->type) {
1151 case H264SEIMessage::kSEIRecoveryPoint:
1152 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1153 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1154 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1155 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1159 DVLOG(4) <<
"Unsupported SEI message";
All the methods that are virtual are virtual for mocking.