From 286a605c638d14562b0e49c2f562c724bd961153 Mon Sep 17 00:00:00 2001 From: bepartofyou <309554135@qq.com> Date: Fri, 8 Oct 2021 21:52:22 +0800 Subject: [PATCH] Fix #2654: Parse width and width from SPS/PPS. Fix #471, #1335, #2539, #1316, #1421 --- trunk/src/kernel/srs_kernel_codec.cpp | 55 +++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp index 69138c5cd..5dc262f35 100644 --- a/trunk/src/kernel/srs_kernel_codec.cpp +++ b/trunk/src/kernel/srs_kernel_codec.cpp @@ -1078,10 +1078,57 @@ srs_error_t SrsFormat::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) if ((err = srs_avc_nalu_read_uev(&bs, pic_height_in_map_units_minus1)) != srs_success) { return srs_error_wrap(err, "read pic_height_in_map_units_minus1");; } - - vcodec->width = (int)(pic_width_in_mbs_minus1 + 1) * 16; - vcodec->height = (int)(pic_height_in_map_units_minus1 + 1) * 16; - + + int8_t frame_mbs_only_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, frame_mbs_only_flag)) != srs_success) { + return srs_error_wrap(err, "read frame_mbs_only_flag");; + } + if(!frame_mbs_only_flag) { + /* Skip mb_adaptive_frame_field_flag */ + int8_t mb_adaptive_frame_field_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, mb_adaptive_frame_field_flag)) != srs_success) { + return srs_error_wrap(err, "read mb_adaptive_frame_field_flag");; + } + } + + /* Skip direct_8x8_inference_flag */ + int8_t direct_8x8_inference_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, direct_8x8_inference_flag)) != srs_success) { + return srs_error_wrap(err, "read direct_8x8_inference_flag");; + } + + /* We need the following value to evaluate offsets, if any */ + int8_t frame_cropping_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, frame_cropping_flag)) != srs_success) { + return srs_error_wrap(err, "read frame_cropping_flag");; + } + int32_t frame_crop_left_offset = 0, frame_crop_right_offset = 0, + frame_crop_top_offset = 0, frame_crop_bottom_offset = 0; + if(frame_cropping_flag) { + if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_left_offset)) != srs_success) { + return srs_error_wrap(err, "read frame_crop_left_offset");; + } + if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_right_offset)) != srs_success) { + return srs_error_wrap(err, "read frame_crop_right_offset");; + } + if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_top_offset)) != srs_success) { + return srs_error_wrap(err, "read frame_crop_top_offset");; + } + if ((err = srs_avc_nalu_read_uev(&bs, frame_crop_bottom_offset)) != srs_success) { + return srs_error_wrap(err, "read frame_crop_bottom_offset");; + } + } + + /* Skip vui_parameters_present_flag */ + int8_t vui_parameters_present_flag = -1; + if ((err = srs_avc_nalu_read_bit(&bs, vui_parameters_present_flag)) != srs_success) { + return srs_error_wrap(err, "read vui_parameters_present_flag");; + } + + vcodec->width = ((pic_width_in_mbs_minus1 + 1) * 16) - frame_crop_left_offset * 2 - frame_crop_right_offset * 2; + vcodec->height = ((2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1) * 16) \ + - (frame_crop_top_offset * 2) - (frame_crop_bottom_offset * 2); + return err; }