This commit solves dangling pointers problems when the content of a parameter set isn't refcounted in the beginning: Now a deep copy of the parameter sets is performed.
Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@googlemail.com> --- libavcodec/cbs_h2645.c | 59 +++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c index 37b0207420..e73706f2e6 100644 --- a/libavcodec/cbs_h2645.c +++ b/libavcodec/cbs_h2645.c @@ -674,7 +674,26 @@ static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx, return 0; } -#define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element) \ + +#define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element, buffer) \ +static AVBufferRef* cbs_h26 ## h26n ## _copy_ ## ps_var(const H26 ## h26n ## Raw ## ps_name *source)\ +{ \ + H26 ## h26n ## Raw ## ps_name *copy; \ + AVBufferRef *copy_ref; \ + copy = av_malloc(sizeof(*source)); \ + if (!copy) \ + return NULL; \ + memcpy(copy, source, sizeof(*source)); \ + copy_ref = av_buffer_create((uint8_t*)copy, sizeof(*source), \ + FREE(h26n, ps_var), NULL, 0); \ + if (!copy_ref) { \ + av_free(copy); \ + return NULL; \ + } \ + cbs_h2645_copy_substructure(h26n, ps_name, ps_var, buffer) \ + return copy_ref; \ +} \ + \ static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \ CodedBitstreamUnit *unit) \ { \ @@ -692,21 +711,43 @@ static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \ if (unit->content_ref) \ priv->ps_var ## _ref[id] = av_buffer_ref(unit->content_ref); \ else \ - priv->ps_var ## _ref[id] = av_buffer_alloc(sizeof(*ps_var)); \ + priv->ps_var ## _ref[id] = cbs_h26 ## h26n ## _copy_ ## ps_var(ps_var); \ if (!priv->ps_var ## _ref[id]) \ return AVERROR(ENOMEM); \ priv->ps_var[id] = (H26 ## h26n ## Raw ## ps_name *)priv->ps_var ## _ref[id]->data; \ - if (!unit->content_ref) \ - memcpy(priv->ps_var[id], ps_var, sizeof(*ps_var)); \ return 0; \ } -cbs_h2645_replace_ps(4, SPS, sps, seq_parameter_set_id) -cbs_h2645_replace_ps(4, PPS, pps, pic_parameter_set_id) -cbs_h2645_replace_ps(5, VPS, vps, vps_video_parameter_set_id) -cbs_h2645_replace_ps(5, SPS, sps, sps_seq_parameter_set_id) -cbs_h2645_replace_ps(5, PPS, pps, pps_pic_parameter_set_id) +#define FREE(h26n, ps_var) NULL +#define cbs_h2645_copy_substructure(h26n, ps_name, ps_var, buffer) +cbs_h2645_replace_ps(4, SPS, sps, seq_parameter_set_id, ) +#undef cbs_h2645_copy_substructure +#undef FREE + +#define FREE(h26n, ps_var) &cbs_h26 ## h26n ## _free_ ## ps_var +#define cbs_h2645_copy_substructure(h26n, ps_name, ps_var, buffer) \ + if (source->buffer) { \ + copy->buffer ## _ref = av_buffer_allocz(SIZE + AV_INPUT_BUFFER_PADDING_SIZE); \ + if (!copy->buffer) { \ + av_buffer_unref(©_ref); \ + return NULL; \ + } \ + copy->buffer = copy->buffer ## _ref->data; \ + memcpy(copy->buffer, source->buffer, SIZE); \ + } + +#define SIZE (copy->pic_size_in_map_units_minus1 + 1) +cbs_h2645_replace_ps(4, PPS, pps, pic_parameter_set_id, slice_group_id) +#undef SIZE + +#define SIZE ((copy->extension_data.bit_length + 7) / 8) +cbs_h2645_replace_ps(5, VPS, vps, vps_video_parameter_set_id, extension_data.data) +cbs_h2645_replace_ps(5, SPS, sps, sps_seq_parameter_set_id, extension_data.data) +cbs_h2645_replace_ps(5, PPS, pps, pps_pic_parameter_set_id, extension_data.data) +#undef SIZE +#undef FREE + static int cbs_h264_read_nal_unit(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit) -- 2.19.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel