Fixes ticket #8622 Signed-off-by: James Almer <jamr...@gmail.com> --- libavcodec/cbs_h2645.c | 1 + libavcodec/cbs_h265.h | 1 + libavcodec/cbs_h265_syntax_template.c | 62 +++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index a60b3217a0..a464b04161 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -552,6 +552,7 @@ static void cbs_h265_free_sei_payload(H265RawSEIPayload *payload) av_buffer_unref(&payload->payload.other.data_ref); break; } + av_buffer_unref(&payload->extension_data.data_ref); } static void cbs_h265_free_sei(void *opaque, uint8_t *content) diff --git a/libavcodec/cbs_h265.h b/libavcodec/cbs_h265.h index 2c1e153ad9..73897f77a4 100644 --- a/libavcodec/cbs_h265.h +++ b/libavcodec/cbs_h265.h @@ -715,6 +715,7 @@ typedef struct H265RawSEIPayload { AVBufferRef *data_ref; } other; } payload; + H265RawExtensionData extension_data; } H265RawSEIPayload; typedef struct H265RawSEI { diff --git a/libavcodec/cbs_h265_syntax_template.c b/libavcodec/cbs_h265_syntax_template.c index 96b9acc1dc..2057527b1a 100644 --- a/libavcodec/cbs_h265_syntax_template.c +++ b/libavcodec/cbs_h265_syntax_template.c @@ -1560,6 +1560,7 @@ static int FUNC(slice_segment_header)(CodedBitstreamContext *ctx, RWContext *rw, static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, H265RawSEIBufferingPeriod *current, + H265RawExtensionData *extension_data, uint32_t *payload_size) { CodedBitstreamH265Context *h265 = ctx->priv_data; @@ -1656,7 +1657,9 @@ static int FUNC(sei_buffering_period)(CodedBitstreamContext *ctx, RWContext *rw, else infer(use_alt_cpb_params_flag, 0); #else - if (current->use_alt_cpb_params_flag) + // If extension data exists, then use_alt_cpb_params_flag is coded in + // the bitstream and must be written even if it's 0. + if (current->use_alt_cpb_params_flag || extension_data->bit_length) flag(use_alt_cpb_params_flag); #endif @@ -2055,11 +2058,47 @@ static int FUNC(sei_alpha_channel_info)(CodedBitstreamContext *ctx, return 0; } +static int FUNC(payload_extension)(CodedBitstreamContext *ctx, RWContext *rw, + H265RawExtensionData *current, uint32_t payload_size, + int cur_pos) +{ + int err; + size_t byte_length, k; + +#ifdef READ + GetBitContext tmp; + int bits_left, payload_zero_bits; + + if (!cbs_h265_payload_extension_present(rw, payload_size, cur_pos)) + return 0; + + bits_left = 8 * payload_size - cur_pos; + tmp = *rw; + if (bits_left > 8) + skip_bits_long(&tmp, bits_left - 8); + payload_zero_bits = get_bits(&tmp, FFMIN(bits_left, 8)); + if (!payload_zero_bits) + return AVERROR_INVALIDDATA; + payload_zero_bits = ff_ctz(payload_zero_bits); + current->bit_length = bits_left - payload_zero_bits - 1; + allocate(current->data, (current->bit_length + 7) / 8); +#endif + + byte_length = (current->bit_length + 7) / 8; + for (k = 0; k < byte_length; k++) { + int length = FFMIN(current->bit_length - k * 8, 8); + xu(length, reserved_payload_extension_data, current->data[k], + 0, MAX_UINT_BITS(length), 0); + } + + return 0; +} + static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, H265RawSEIPayload *current, int prefix) { int err, i; - int start_position, end_position; + int start_position, current_position, end_position; #ifdef READ start_position = get_bits_count(rw); @@ -2091,8 +2130,15 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, CHECK(FUNC(sei_ ## name)(ctx, rw, ¤t->payload.name, \ ¤t->payload_size)); \ break +#define SEI_TYPE_E(type, prefix_valid, suffix_valid, name) \ + case HEVC_SEI_TYPE_ ## type: \ + SEI_TYPE_CHECK_VALID(name, prefix_valid, suffix_valid); \ + CHECK(FUNC(sei_ ## name)(ctx, rw, ¤t->payload.name, \ + ¤t->extension_data, \ + ¤t->payload_size)); \ + break - SEI_TYPE_S(BUFFERING_PERIOD, 1, 0, buffering_period); + SEI_TYPE_E(BUFFERING_PERIOD, 1, 0, buffering_period); SEI_TYPE_N(PICTURE_TIMING, 1, 0, pic_timing); SEI_TYPE_N(PAN_SCAN_RECT, 1, 0, pan_scan_rect); SEI_TYPE_S(USER_DATA_REGISTERED_ITU_T_T35, @@ -2123,7 +2169,15 @@ static int FUNC(sei_payload)(CodedBitstreamContext *ctx, RWContext *rw, } } - if (byte_alignment(rw)) { +#ifdef READ + current_position = get_bits_count(rw) - start_position; + if (current_position != 8 * current->payload_size) { +#else + current_position = put_bits_count(rw) - start_position; + if (byte_alignment(rw) || current->extension_data.bit_length) { +#endif + CHECK(FUNC(payload_extension)(ctx, rw, ¤t->extension_data, + current->payload_size, current_position)); fixed(1, bit_equal_to_one, 1); while (byte_alignment(rw)) fixed(1, bit_equal_to_zero, 0); -- 2.26.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".