[FFmpeg-devel] [PATCH 2/6] cbs_h2645: Do a deep copy for parameter sets
Andreas Rheinhardt
andreas.rheinhardt at googlemail.com
Fri Nov 9 07:31:34 EET 2018
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.rheinhardt at 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
More information about the ffmpeg-devel
mailing list