[FFmpeg-devel,3/5] cbs_h2645: Implement copy-functions for parameter sets

Submitted by Andreas Rheinhardt on Nov. 24, 2018, 1:55 a.m.

Details

Message ID 20181124015539.7164-4-andreas.rheinhardt@googlemail.com
State Superseded
Headers show

Commit Message

Andreas Rheinhardt Nov. 24, 2018, 1:55 a.m.
and use them to replace the context's parameter sets.

This fixes a dangling pointers problem with the parameter sets
held in the CodedBitstreamH26xContext that occurs when the parameter
sets were not reference-counted initially.

The functions to free the parameter sets that have a special free
callback are now also created via the same macro as the copy functions.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@googlemail.com>
---
 libavcodec/cbs_h2645.c | 47 ++++++++++++++++--------------------------
 1 file changed, 18 insertions(+), 29 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavcodec/cbs_h2645.c b/libavcodec/cbs_h2645.c
index 7296c4cf29..b40cf92a7b 100644
--- a/libavcodec/cbs_h2645.c
+++ b/libavcodec/cbs_h2645.c
@@ -413,14 +413,25 @@  static int cbs_h2645_read_more_rbsp_data(GetBitContext *gbc)
 #undef byte_alignment
 #undef allocate
 
-
-static void cbs_h264_free_pps(void *unit, uint8_t *content)
+static AVBufferRef *cbs_h264_copy_sps(const H264RawSPS *source)
 {
-    H264RawPPS *pps = (H264RawPPS*)content;
-    av_buffer_unref(&pps->slice_group_id_ref);
-    av_freep(&content);
+    AVBufferRef *ref = av_buffer_alloc(sizeof(H264RawSPS));
+    if (!ref)
+        return NULL;
+    memcpy(ref->data, source, sizeof(H264RawSPS));
+    return ref;
 }
 
+cbs_copy_free(h264, H264RawPPS, pps, slice_group_id,
+              pic_size_in_map_units_minus1, BYTES, 1)
+
+cbs_copy_free(h265, H265RawVPS, vps, extension_data.data,
+              extension_data.bit_length, BITS, 0)
+cbs_copy_free(h265, H265RawSPS, sps, extension_data.data,
+              extension_data.bit_length, BITS, 0)
+cbs_copy_free(h265, H265RawPPS, pps, extension_data.data,
+              extension_data.bit_length, BITS, 0)
+
 static void cbs_h264_free_sei_payload(H264RawSEIPayload *payload)
 {
     switch (payload->payload_type) {
@@ -459,27 +470,6 @@  static void cbs_h264_free_slice(void *unit, uint8_t *content)
     av_freep(&content);
 }
 
-static void cbs_h265_free_vps(void *unit, uint8_t *content)
-{
-    H265RawVPS *vps = (H265RawVPS*)content;
-    av_buffer_unref(&vps->extension_data.data_ref);
-    av_freep(&content);
-}
-
-static void cbs_h265_free_sps(void *unit, uint8_t *content)
-{
-    H265RawSPS *sps = (H265RawSPS*)content;
-    av_buffer_unref(&sps->extension_data.data_ref);
-    av_freep(&content);
-}
-
-static void cbs_h265_free_pps(void *unit, uint8_t *content)
-{
-    H265RawPPS *pps = (H265RawPPS*)content;
-    av_buffer_unref(&pps->extension_data.data_ref);
-    av_freep(&content);
-}
-
 static void cbs_h265_free_slice(void *unit, uint8_t *content)
 {
     H265RawSlice *slice = (H265RawSlice*)content;
@@ -721,6 +711,7 @@  static int cbs_h2645_split_fragment(CodedBitstreamContext *ctx,
     return 0;
 }
 
+
 #define cbs_h2645_replace_ps(h26n, ps_name, ps_var, id_element) \
 static int cbs_h26 ## h26n ## _replace_ ## ps_var(CodedBitstreamContext *ctx, \
                                                   CodedBitstreamUnit *unit)  \
@@ -739,12 +730,10 @@  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; \
 }