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; \
27bool 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;
90bool H264SliceHeader::IsPSlice()
const {
91 return (slice_type % 5 == kPSlice);
94bool H264SliceHeader::IsBSlice()
const {
95 return (slice_type % 5 == kBSlice);
98bool H264SliceHeader::IsISlice()
const {
99 return (slice_type % 5 == kISlice);
102bool H264SliceHeader::IsSPSlice()
const {
103 return (slice_type % 5 == kSPSlice);
106bool 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; \
181static const int kTableSarWidth[] = {0, 1, 12, 10, 16, 40, 24, 20, 32,
182 80, 18, 15, 64, 160, 4, 3, 2};
183static const int kTableSarHeight[] = {0, 1, 11, 11, 11, 33, 11, 11, 11,
184 33, 11, 11, 33, 99, 3, 2, 1};
185static_assert(std::size(kTableSarWidth) == std::size(kTableSarHeight),
186 "sar_tables_must_have_same_size");
188H264Parser::H264Parser() {}
190H264Parser::~H264Parser() {}
192const H264Pps* H264Parser::GetPps(
int pps_id) {
193 return active_PPSes_[pps_id].get();
196const H264Sps* H264Parser::GetSps(
int sps_id) {
197 return active_SPSes_[sps_id].get();
201static const int kDefault4x4Intra[kH264ScalingList4x4Length] = {
202 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42,
205static const int kDefault4x4Inter[kH264ScalingList4x4Length] = {
206 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34,
209static 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,
216static const int kDefault8x8Inter[kH264ScalingList8x8Length] = {
217 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21,
218 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24,
219 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27,
220 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
223static inline void DefaultScalingList4x4(
225 int scaling_list4x4[][kH264ScalingList4x4Length]) {
229 memcpy(scaling_list4x4[i], kDefault4x4Intra,
sizeof(kDefault4x4Intra));
231 memcpy(scaling_list4x4[i], kDefault4x4Inter,
sizeof(kDefault4x4Inter));
234static inline void DefaultScalingList8x8(
236 int scaling_list8x8[][kH264ScalingList8x8Length]) {
240 memcpy(scaling_list8x8[i], kDefault8x8Intra,
sizeof(kDefault8x8Intra));
242 memcpy(scaling_list8x8[i], kDefault8x8Inter,
sizeof(kDefault8x8Inter));
245static void FallbackScalingList4x4(
247 const int default_scaling_list_intra[],
248 const int default_scaling_list_inter[],
249 int scaling_list4x4[][kH264ScalingList4x4Length]) {
250 static const int kScalingList4x4ByteSize =
251 sizeof(scaling_list4x4[0][0]) * kH264ScalingList4x4Length;
255 memcpy(scaling_list4x4[i], default_scaling_list_intra,
256 kScalingList4x4ByteSize);
260 memcpy(scaling_list4x4[i], scaling_list4x4[0], kScalingList4x4ByteSize);
264 memcpy(scaling_list4x4[i], scaling_list4x4[1], kScalingList4x4ByteSize);
268 memcpy(scaling_list4x4[i], default_scaling_list_inter,
269 kScalingList4x4ByteSize);
273 memcpy(scaling_list4x4[i], scaling_list4x4[3], kScalingList4x4ByteSize);
277 memcpy(scaling_list4x4[i], scaling_list4x4[4], kScalingList4x4ByteSize);
281 NOTIMPLEMENTED() <<
"index out of range [0,5]: " << i;
286static void FallbackScalingList8x8(
288 const int default_scaling_list_intra[],
289 const int default_scaling_list_inter[],
290 int scaling_list8x8[][kH264ScalingList8x8Length]) {
291 static const int kScalingList8x8ByteSize =
292 sizeof(scaling_list8x8[0][0]) * kH264ScalingList8x8Length;
296 memcpy(scaling_list8x8[i], default_scaling_list_intra,
297 kScalingList8x8ByteSize);
301 memcpy(scaling_list8x8[i], default_scaling_list_inter,
302 kScalingList8x8ByteSize);
306 memcpy(scaling_list8x8[i], scaling_list8x8[0], kScalingList8x8ByteSize);
310 memcpy(scaling_list8x8[i], scaling_list8x8[1], kScalingList8x8ByteSize);
314 memcpy(scaling_list8x8[i], scaling_list8x8[2], kScalingList8x8ByteSize);
318 memcpy(scaling_list8x8[i], scaling_list8x8[3], kScalingList8x8ByteSize);
322 NOTIMPLEMENTED() <<
"index out of range [0,5]: " << i;
327H264Parser::Result H264Parser::ParseScalingList(H26xBitReader* br,
336 *use_default =
false;
338 for (
int j = 0; j < size; ++j) {
339 if (next_scale != 0) {
340 READ_SE_OR_RETURN(&delta_scale);
341 IN_RANGE_OR_RETURN(delta_scale, -128, 127);
342 next_scale = (last_scale + delta_scale + 256) & 0xff;
344 if (j == 0 && next_scale == 0) {
350 scaling_list[j] = (next_scale == 0) ? last_scale : next_scale;
351 last_scale = scaling_list[j];
357H264Parser::Result H264Parser::ParseSpsScalingLists(H26xBitReader* br,
360 bool seq_scaling_list_present_flag;
365 for (
int i = 0; i < 6; ++i) {
366 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
368 if (seq_scaling_list_present_flag) {
369 res = ParseScalingList(br, std::size(sps->scaling_list4x4[i]),
370 sps->scaling_list4x4[i], &use_default);
375 DefaultScalingList4x4(i, sps->scaling_list4x4);
378 FallbackScalingList4x4(i, kDefault4x4Intra, kDefault4x4Inter,
379 sps->scaling_list4x4);
384 for (
int i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) {
385 READ_BOOL_OR_RETURN(&seq_scaling_list_present_flag);
387 if (seq_scaling_list_present_flag) {
388 res = ParseScalingList(br, std::size(sps->scaling_list8x8[i]),
389 sps->scaling_list8x8[i], &use_default);
394 DefaultScalingList8x8(i, sps->scaling_list8x8);
397 FallbackScalingList8x8(i, kDefault8x8Intra, kDefault8x8Inter,
398 sps->scaling_list8x8);
405H264Parser::Result H264Parser::ParsePpsScalingLists(H26xBitReader* 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, std::size(pps->scaling_list4x4[i]),
418 pps->scaling_list4x4[i], &use_default);
423 DefaultScalingList4x4(i, pps->scaling_list4x4);
426 if (sps.seq_scaling_matrix_present_flag) {
428 FallbackScalingList4x4(i, kDefault4x4Intra, kDefault4x4Inter,
429 pps->scaling_list4x4);
432 FallbackScalingList4x4(i, sps.scaling_list4x4[0],
433 sps.scaling_list4x4[3], 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(i, kDefault8x8Intra, kDefault8x8Inter,
455 pps->scaling_list8x8);
458 FallbackScalingList8x8(i, sps.scaling_list8x8[0],
459 sps.scaling_list8x8[1], pps->scaling_list8x8);
467H264Parser::Result H264Parser::ParseAndIgnoreHRDParameters(
469 bool* hrd_parameters_present) {
471 READ_BOOL_OR_RETURN(&data);
475 *hrd_parameters_present =
true;
478 READ_UE_OR_RETURN(&cpb_cnt_minus1);
479 IN_RANGE_OR_RETURN(cpb_cnt_minus1, 0, 31);
480 READ_BITS_OR_RETURN(8, &data);
481 for (
int i = 0; i <= cpb_cnt_minus1; ++i) {
482 READ_UE_OR_RETURN(&data);
483 READ_UE_OR_RETURN(&data);
484 READ_BOOL_OR_RETURN(&data);
486 READ_BITS_OR_RETURN(20, &data);
491H264Parser::Result H264Parser::ParseVUIParameters(H26xBitReader* br,
493 bool aspect_ratio_info_present_flag;
494 READ_BOOL_OR_RETURN(&aspect_ratio_info_present_flag);
495 if (aspect_ratio_info_present_flag) {
496 int aspect_ratio_idc;
497 READ_BITS_OR_RETURN(8, &aspect_ratio_idc);
498 if (aspect_ratio_idc == kExtendedSar) {
499 READ_BITS_OR_RETURN(16, &sps->sar_width);
500 READ_BITS_OR_RETURN(16, &sps->sar_height);
502 const int max_aspect_ratio_idc = std::size(kTableSarWidth) - 1;
503 IN_RANGE_OR_RETURN(aspect_ratio_idc, 0, max_aspect_ratio_idc);
504 sps->sar_width = kTableSarWidth[aspect_ratio_idc];
505 sps->sar_height = kTableSarHeight[aspect_ratio_idc];
511 READ_BOOL_OR_RETURN(&data);
513 READ_BOOL_OR_RETURN(&data);
515 READ_BOOL_OR_RETURN(&data);
517 READ_BITS_OR_RETURN(3, &data);
518 READ_BOOL_OR_RETURN(&data);
519 READ_BOOL_OR_RETURN(&data);
521 READ_BITS_OR_RETURN(8, &sps->color_primaries);
522 READ_BITS_OR_RETURN(8, &sps->transfer_characteristics);
523 READ_BITS_OR_RETURN(8, &sps->matrix_coefficients);
527 READ_BOOL_OR_RETURN(&data);
529 READ_UE_OR_RETURN(&data);
530 READ_UE_OR_RETURN(&data);
534 READ_BOOL_OR_RETURN(&sps->timing_info_present_flag);
535 if (sps->timing_info_present_flag) {
536 READ_LONG_OR_RETURN(&sps->num_units_in_tick);
537 READ_LONG_OR_RETURN(&sps->time_scale);
538 READ_BOOL_OR_RETURN(&sps->fixed_frame_rate_flag);
542 bool hrd_parameters_present =
false;
543 Result res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
548 res = ParseAndIgnoreHRDParameters(br, &hrd_parameters_present);
552 if (hrd_parameters_present)
553 READ_BOOL_OR_RETURN(&data);
555 READ_BOOL_OR_RETURN(&data);
556 READ_BOOL_OR_RETURN(&sps->bitstream_restriction_flag);
557 if (sps->bitstream_restriction_flag) {
558 READ_BOOL_OR_RETURN(&data);
559 READ_UE_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(&sps->max_num_reorder_frames);
564 READ_UE_OR_RETURN(&sps->max_dec_frame_buffering);
565 TRUE_OR_RETURN(sps->max_dec_frame_buffering >= sps->max_num_ref_frames);
566 IN_RANGE_OR_RETURN(sps->max_num_reorder_frames, 0,
567 sps->max_dec_frame_buffering);
573static void FillDefaultSeqScalingLists(H264Sps* sps) {
574 for (
int i = 0; i < 6; ++i)
575 for (
int j = 0; j < kH264ScalingList4x4Length; ++j)
576 sps->scaling_list4x4[i][j] = 16;
578 for (
int i = 0; i < 6; ++i)
579 for (
int j = 0; j < kH264ScalingList8x8Length; ++j)
580 sps->scaling_list8x8[i][j] = 16;
583H264Parser::Result H264Parser::ParseSps(
const Nalu& nalu,
int* sps_id) {
587 H26xBitReader reader;
588 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
589 H26xBitReader* br = &reader;
593 std::unique_ptr<H264Sps> sps(
new H264Sps());
595 READ_BITS_OR_RETURN(8, &sps->profile_idc);
596 READ_BOOL_OR_RETURN(&sps->constraint_set0_flag);
597 READ_BOOL_OR_RETURN(&sps->constraint_set1_flag);
598 READ_BOOL_OR_RETURN(&sps->constraint_set2_flag);
599 READ_BOOL_OR_RETURN(&sps->constraint_set3_flag);
600 READ_BOOL_OR_RETURN(&sps->constraint_set4_flag);
601 READ_BOOL_OR_RETURN(&sps->constraint_set5_flag);
602 READ_BITS_OR_RETURN(2, &data);
603 READ_BITS_OR_RETURN(8, &sps->level_idc);
604 READ_UE_OR_RETURN(&sps->seq_parameter_set_id);
605 TRUE_OR_RETURN(sps->seq_parameter_set_id < 32);
607 if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
608 sps->profile_idc == 122 || sps->profile_idc == 244 ||
609 sps->profile_idc == 44 || sps->profile_idc == 83 ||
610 sps->profile_idc == 86 || sps->profile_idc == 118 ||
611 sps->profile_idc == 128) {
612 READ_UE_OR_RETURN(&sps->chroma_format_idc);
613 TRUE_OR_RETURN(sps->chroma_format_idc < 4);
615 if (sps->chroma_format_idc == 3)
616 READ_BOOL_OR_RETURN(&sps->separate_colour_plane_flag);
618 READ_UE_OR_RETURN(&sps->bit_depth_luma_minus8);
619 TRUE_OR_RETURN(sps->bit_depth_luma_minus8 < 7);
621 READ_UE_OR_RETURN(&sps->bit_depth_chroma_minus8);
622 TRUE_OR_RETURN(sps->bit_depth_chroma_minus8 < 7);
624 READ_BOOL_OR_RETURN(&sps->qpprime_y_zero_transform_bypass_flag);
625 READ_BOOL_OR_RETURN(&sps->seq_scaling_matrix_present_flag);
627 if (sps->seq_scaling_matrix_present_flag) {
628 DVLOG(4) <<
"Scaling matrix present";
629 res = ParseSpsScalingLists(br, sps.get());
633 FillDefaultSeqScalingLists(sps.get());
636 sps->chroma_format_idc = 1;
637 FillDefaultSeqScalingLists(sps.get());
640 if (sps->separate_colour_plane_flag)
641 sps->chroma_array_type = 0;
643 sps->chroma_array_type = sps->chroma_format_idc;
645 READ_UE_OR_RETURN(&sps->log2_max_frame_num_minus4);
646 TRUE_OR_RETURN(sps->log2_max_frame_num_minus4 < 13);
648 READ_UE_OR_RETURN(&sps->pic_order_cnt_type);
649 TRUE_OR_RETURN(sps->pic_order_cnt_type < 3);
651 sps->expected_delta_per_pic_order_cnt_cycle = 0;
652 if (sps->pic_order_cnt_type == 0) {
653 READ_UE_OR_RETURN(&sps->log2_max_pic_order_cnt_lsb_minus4);
654 TRUE_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 < 13);
655 }
else if (sps->pic_order_cnt_type == 1) {
656 READ_BOOL_OR_RETURN(&sps->delta_pic_order_always_zero_flag);
657 READ_SE_OR_RETURN(&sps->offset_for_non_ref_pic);
658 READ_SE_OR_RETURN(&sps->offset_for_top_to_bottom_field);
659 READ_UE_OR_RETURN(&sps->num_ref_frames_in_pic_order_cnt_cycle);
660 TRUE_OR_RETURN(sps->num_ref_frames_in_pic_order_cnt_cycle < 255);
662 for (
int i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) {
663 READ_SE_OR_RETURN(&sps->offset_for_ref_frame[i]);
664 sps->expected_delta_per_pic_order_cnt_cycle +=
665 sps->offset_for_ref_frame[i];
669 READ_UE_OR_RETURN(&sps->max_num_ref_frames);
670 READ_BOOL_OR_RETURN(&sps->gaps_in_frame_num_value_allowed_flag);
672 READ_UE_OR_RETURN(&sps->pic_width_in_mbs_minus1);
673 READ_UE_OR_RETURN(&sps->pic_height_in_map_units_minus1);
675 READ_BOOL_OR_RETURN(&sps->frame_mbs_only_flag);
676 if (!sps->frame_mbs_only_flag)
677 READ_BOOL_OR_RETURN(&sps->mb_adaptive_frame_field_flag);
679 READ_BOOL_OR_RETURN(&sps->direct_8x8_inference_flag);
681 READ_BOOL_OR_RETURN(&sps->frame_cropping_flag);
682 if (sps->frame_cropping_flag) {
683 READ_UE_OR_RETURN(&sps->frame_crop_left_offset);
684 READ_UE_OR_RETURN(&sps->frame_crop_right_offset);
685 READ_UE_OR_RETURN(&sps->frame_crop_top_offset);
686 READ_UE_OR_RETURN(&sps->frame_crop_bottom_offset);
689 READ_BOOL_OR_RETURN(&sps->vui_parameters_present_flag);
690 if (sps->vui_parameters_present_flag) {
691 DVLOG(4) <<
"VUI parameters present";
692 res = ParseVUIParameters(br, sps.get());
698 *sps_id = sps->seq_parameter_set_id;
699 active_SPSes_[*sps_id] = std::move(sps);
704H264Parser::Result H264Parser::ParsePps(
const Nalu& nalu,
int* pps_id) {
708 H26xBitReader reader;
709 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
710 H26xBitReader* br = &reader;
714 std::unique_ptr<H264Pps> pps(
new H264Pps());
716 READ_UE_OR_RETURN(&pps->pic_parameter_set_id);
717 READ_UE_OR_RETURN(&pps->seq_parameter_set_id);
718 TRUE_OR_RETURN(pps->seq_parameter_set_id < 32);
720 sps = GetSps(pps->seq_parameter_set_id);
723 READ_BOOL_OR_RETURN(&pps->entropy_coding_mode_flag);
724 READ_BOOL_OR_RETURN(&pps->bottom_field_pic_order_in_frame_present_flag);
726 READ_UE_OR_RETURN(&pps->num_slice_groups_minus1);
727 if (pps->num_slice_groups_minus1 > 1) {
728 LOG_ERROR_ONCE(
"Slice groups not supported");
729 return kUnsupportedStream;
732 READ_UE_OR_RETURN(&pps->num_ref_idx_l0_default_active_minus1);
733 TRUE_OR_RETURN(pps->num_ref_idx_l0_default_active_minus1 < 32);
735 READ_UE_OR_RETURN(&pps->num_ref_idx_l1_default_active_minus1);
736 TRUE_OR_RETURN(pps->num_ref_idx_l1_default_active_minus1 < 32);
738 READ_BOOL_OR_RETURN(&pps->weighted_pred_flag);
739 READ_BITS_OR_RETURN(2, &pps->weighted_bipred_idc);
740 TRUE_OR_RETURN(pps->weighted_bipred_idc < 3);
742 READ_SE_OR_RETURN(&pps->pic_init_qp_minus26);
743 IN_RANGE_OR_RETURN(pps->pic_init_qp_minus26, -26, 25);
745 READ_SE_OR_RETURN(&pps->pic_init_qs_minus26);
746 IN_RANGE_OR_RETURN(pps->pic_init_qs_minus26, -26, 25);
748 READ_SE_OR_RETURN(&pps->chroma_qp_index_offset);
749 IN_RANGE_OR_RETURN(pps->chroma_qp_index_offset, -12, 12);
750 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
752 READ_BOOL_OR_RETURN(&pps->deblocking_filter_control_present_flag);
753 READ_BOOL_OR_RETURN(&pps->constrained_intra_pred_flag);
754 READ_BOOL_OR_RETURN(&pps->redundant_pic_cnt_present_flag);
756 if (br->HasMoreRBSPData()) {
757 READ_BOOL_OR_RETURN(&pps->transform_8x8_mode_flag);
758 READ_BOOL_OR_RETURN(&pps->pic_scaling_matrix_present_flag);
760 if (pps->pic_scaling_matrix_present_flag) {
761 DVLOG(4) <<
"Picture scaling matrix present";
762 res = ParsePpsScalingLists(br, *sps, pps.get());
767 READ_SE_OR_RETURN(&pps->second_chroma_qp_index_offset);
771 *pps_id = pps->pic_parameter_set_id;
772 active_PPSes_[*pps_id] = std::move(pps);
777H264Parser::Result H264Parser::ParseRefPicListModification(
779 int num_ref_idx_active_minus1,
780 H264ModificationOfPicNum* ref_list_mods) {
781 H264ModificationOfPicNum* pic_num_mod;
783 if (num_ref_idx_active_minus1 >= 32)
784 return kInvalidStream;
786 for (
int i = 0; i < 32; ++i) {
787 pic_num_mod = &ref_list_mods[i];
788 READ_UE_OR_RETURN(&pic_num_mod->modification_of_pic_nums_idc);
789 TRUE_OR_RETURN(pic_num_mod->modification_of_pic_nums_idc < 4);
791 switch (pic_num_mod->modification_of_pic_nums_idc) {
794 READ_UE_OR_RETURN(&pic_num_mod->abs_diff_pic_num_minus1);
798 READ_UE_OR_RETURN(&pic_num_mod->long_term_pic_num);
804 return kInvalidStream;
808 return kInvalidStream;
814 int modification_of_pic_nums_idc;
815 READ_UE_OR_RETURN(&modification_of_pic_nums_idc);
816 TRUE_OR_RETURN(modification_of_pic_nums_idc == 3);
821H264Parser::Result H264Parser::ParseRefPicListModifications(
823 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);
849H264Parser::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;
894H264Parser::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(
905 br, shdr->num_ref_idx_l0_active_minus1, sps.chroma_array_type,
906 shdr->luma_log2_weight_denom, shdr->chroma_log2_weight_denom,
907 &shdr->pred_weight_table_l0);
911 if (shdr->IsBSlice()) {
912 res = ParseWeightingFactors(
913 br, shdr->num_ref_idx_l1_active_minus1, sps.chroma_array_type,
914 shdr->luma_log2_weight_denom, shdr->chroma_log2_weight_denom,
915 &shdr->pred_weight_table_l1);
923H264Parser::Result H264Parser::ParseDecRefPicMarking(H26xBitReader* br,
924 H264SliceHeader* shdr) {
925 if (shdr->idr_pic_flag) {
926 READ_BOOL_OR_RETURN(&shdr->no_output_of_prior_pics_flag);
927 READ_BOOL_OR_RETURN(&shdr->long_term_reference_flag);
929 READ_BOOL_OR_RETURN(&shdr->adaptive_ref_pic_marking_mode_flag);
931 H264DecRefPicMarking* marking;
932 if (shdr->adaptive_ref_pic_marking_mode_flag) {
934 for (i = 0; i < std::size(shdr->ref_pic_marking); ++i) {
935 marking = &shdr->ref_pic_marking[i];
937 READ_UE_OR_RETURN(&marking->memory_mgmnt_control_operation);
938 if (marking->memory_mgmnt_control_operation == 0)
941 if (marking->memory_mgmnt_control_operation == 1 ||
942 marking->memory_mgmnt_control_operation == 3)
943 READ_UE_OR_RETURN(&marking->difference_of_pic_nums_minus1);
945 if (marking->memory_mgmnt_control_operation == 2)
946 READ_UE_OR_RETURN(&marking->long_term_pic_num);
948 if (marking->memory_mgmnt_control_operation == 3 ||
949 marking->memory_mgmnt_control_operation == 6)
950 READ_UE_OR_RETURN(&marking->long_term_frame_idx);
952 if (marking->memory_mgmnt_control_operation == 4)
953 READ_UE_OR_RETURN(&marking->max_long_term_frame_idx_plus1);
955 if (marking->memory_mgmnt_control_operation > 6)
956 return kInvalidStream;
959 if (i == std::size(shdr->ref_pic_marking)) {
960 LOG_ERROR_ONCE(
"Ran out of dec ref pic marking fields");
961 return kUnsupportedStream;
969H264Parser::Result H264Parser::ParseSliceHeader(
const Nalu& nalu,
970 H264SliceHeader* shdr) {
975 H26xBitReader reader;
976 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
977 H26xBitReader* br = &reader;
981 shdr->idr_pic_flag = (nalu.type() == 5);
982 shdr->nal_ref_idc = nalu.ref_idc();
983 shdr->nalu_data = nalu.data();
984 shdr->nalu_size = nalu.header_size() + nalu.payload_size();
986 READ_UE_OR_RETURN(&shdr->first_mb_in_slice);
987 READ_UE_OR_RETURN(&shdr->slice_type);
988 TRUE_OR_RETURN(shdr->slice_type < 10);
990 READ_UE_OR_RETURN(&shdr->pic_parameter_set_id);
992 pps = GetPps(shdr->pic_parameter_set_id);
995 sps = GetSps(pps->seq_parameter_set_id);
998 if (sps->separate_colour_plane_flag) {
999 LOG_ERROR_ONCE(
"Interlaced streams not supported");
1000 return kUnsupportedStream;
1003 READ_BITS_OR_RETURN(sps->log2_max_frame_num_minus4 + 4, &shdr->frame_num);
1004 if (!sps->frame_mbs_only_flag) {
1005 READ_BOOL_OR_RETURN(&shdr->field_pic_flag);
1006 if (shdr->field_pic_flag) {
1007 LOG_ERROR_ONCE(
"Interlaced streams not supported");
1008 return kUnsupportedStream;
1012 if (shdr->idr_pic_flag)
1013 READ_UE_OR_RETURN(&shdr->idr_pic_id);
1015 if (sps->pic_order_cnt_type == 0) {
1016 READ_BITS_OR_RETURN(sps->log2_max_pic_order_cnt_lsb_minus4 + 4,
1017 &shdr->pic_order_cnt_lsb);
1018 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1019 !shdr->field_pic_flag)
1020 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt_bottom);
1023 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
1024 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[0]);
1025 if (pps->bottom_field_pic_order_in_frame_present_flag &&
1026 !shdr->field_pic_flag)
1027 READ_SE_OR_RETURN(&shdr->delta_pic_order_cnt[1]);
1030 if (pps->redundant_pic_cnt_present_flag) {
1031 READ_UE_OR_RETURN(&shdr->redundant_pic_cnt);
1032 TRUE_OR_RETURN(shdr->redundant_pic_cnt < 128);
1035 if (shdr->IsBSlice())
1036 READ_BOOL_OR_RETURN(&shdr->direct_spatial_mv_pred_flag);
1038 if (shdr->IsPSlice() || shdr->IsSPSlice() || shdr->IsBSlice()) {
1039 READ_BOOL_OR_RETURN(&shdr->num_ref_idx_active_override_flag);
1040 if (shdr->num_ref_idx_active_override_flag) {
1041 READ_UE_OR_RETURN(&shdr->num_ref_idx_l0_active_minus1);
1042 if (shdr->IsBSlice())
1043 READ_UE_OR_RETURN(&shdr->num_ref_idx_l1_active_minus1);
1045 shdr->num_ref_idx_l0_active_minus1 =
1046 pps->num_ref_idx_l0_default_active_minus1;
1047 if (shdr->IsBSlice()) {
1048 shdr->num_ref_idx_l1_active_minus1 =
1049 pps->num_ref_idx_l1_default_active_minus1;
1053 if (shdr->field_pic_flag) {
1054 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 32);
1055 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 32);
1057 TRUE_OR_RETURN(shdr->num_ref_idx_l0_active_minus1 < 16);
1058 TRUE_OR_RETURN(shdr->num_ref_idx_l1_active_minus1 < 16);
1061 if (nalu.type() == Nalu::H264_CodedSliceExtension) {
1062 return kUnsupportedStream;
1064 res = ParseRefPicListModifications(br, shdr);
1069 if ((pps->weighted_pred_flag && (shdr->IsPSlice() || shdr->IsSPSlice())) ||
1070 (pps->weighted_bipred_idc == 1 && shdr->IsBSlice())) {
1071 res = ParsePredWeightTable(br, *sps, shdr);
1076 if (nalu.ref_idc() != 0) {
1077 res = ParseDecRefPicMarking(br, shdr);
1082 if (pps->entropy_coding_mode_flag && !shdr->IsISlice() &&
1083 !shdr->IsSISlice()) {
1084 READ_UE_OR_RETURN(&shdr->cabac_init_idc);
1085 TRUE_OR_RETURN(shdr->cabac_init_idc < 3);
1088 READ_SE_OR_RETURN(&shdr->slice_qp_delta);
1090 if (shdr->IsSPSlice() || shdr->IsSISlice()) {
1091 if (shdr->IsSPSlice())
1092 READ_BOOL_OR_RETURN(&shdr->sp_for_switch_flag);
1093 READ_SE_OR_RETURN(&shdr->slice_qs_delta);
1096 if (pps->deblocking_filter_control_present_flag) {
1097 READ_UE_OR_RETURN(&shdr->disable_deblocking_filter_idc);
1098 TRUE_OR_RETURN(shdr->disable_deblocking_filter_idc < 3);
1100 if (shdr->disable_deblocking_filter_idc != 1) {
1101 READ_SE_OR_RETURN(&shdr->slice_alpha_c0_offset_div2);
1102 IN_RANGE_OR_RETURN(shdr->slice_alpha_c0_offset_div2, -6, 6);
1104 READ_SE_OR_RETURN(&shdr->slice_beta_offset_div2);
1105 IN_RANGE_OR_RETURN(shdr->slice_beta_offset_div2, -6, 6);
1109 if (pps->num_slice_groups_minus1 > 0) {
1110 LOG_ERROR_ONCE(
"Slice groups not supported");
1111 return kUnsupportedStream;
1114 shdr->header_bit_size = nalu.payload_size() * 8 - br->NumBitsLeft();
1118H264Parser::Result H264Parser::ParseSEI(
const Nalu& nalu,
1119 H264SEIMessage* sei_msg) {
1121 H26xBitReader reader;
1122 reader.Initialize(nalu.data() + nalu.header_size(), nalu.payload_size());
1123 H26xBitReader* br = &reader;
1127 READ_BITS_OR_RETURN(8, &
byte);
1128 while (
byte == 0xff) {
1129 sei_msg->type += 255;
1130 READ_BITS_OR_RETURN(8, &
byte);
1132 sei_msg->type += byte;
1134 READ_BITS_OR_RETURN(8, &
byte);
1135 while (
byte == 0xff) {
1136 sei_msg->payload_size += 255;
1137 READ_BITS_OR_RETURN(8, &
byte);
1139 sei_msg->payload_size += byte;
1141 DVLOG(4) <<
"Found SEI message type: " << sei_msg->type
1142 <<
" payload size: " << sei_msg->payload_size;
1144 switch (sei_msg->type) {
1145 case H264SEIMessage::kSEIRecoveryPoint:
1146 READ_UE_OR_RETURN(&sei_msg->recovery_point.recovery_frame_cnt);
1147 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.exact_match_flag);
1148 READ_BOOL_OR_RETURN(&sei_msg->recovery_point.broken_link_flag);
1149 READ_BITS_OR_RETURN(2, &sei_msg->recovery_point.changing_slice_group_idc);
1153 DVLOG(4) <<
"Unsupported SEI message";
All the methods that are virtual are virtual for mocking.