From 98ac557e876ee8e14f7155e50d314819310f2791 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 22 Nov 2013 09:49:30 +0100 Subject: [PATCH] vaapipostproc: fix memory leaks with advanced deinterlacing. Fix memory leaks with advanced deinterlacing, i.e. when we keep track of past buffers. Completely reset the deinterlace state, thus destroying any buffer currently held, on _start(), _stop() and _destroy(). --- gst/vaapi/gstvaapipostproc.c | 97 ++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index 2ec8397..1bf66cb 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -189,6 +189,55 @@ gst_vaapi_deinterlace_mode_get_type(void) return deinterlace_mode_type; } +static void +ds_reset(GstVaapiDeinterlaceState *ds) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) + gst_buffer_replace(&ds->buffers[i], NULL); + ds->buffers_index = 0; + ds->num_surfaces = 0; + ds->deint = FALSE; + ds->tff = FALSE; +} + +static void +ds_add_buffer(GstVaapiDeinterlaceState *ds, GstBuffer *buf) +{ + gst_buffer_replace(&ds->buffers[ds->buffers_index], buf); + ds->buffers_index = (ds->buffers_index + 1) % G_N_ELEMENTS(ds->buffers); +} + +static inline GstBuffer * +ds_get_buffer(GstVaapiDeinterlaceState *ds, guint index) +{ + /* Note: the index increases towards older buffers. + i.e. buffer at index 0 means the immediately preceding buffer + in the history, buffer at index 1 means the one preceding the + surface at index 0, etc. */ + const guint n = ds->buffers_index + G_N_ELEMENTS(ds->buffers) - index - 1; + return ds->buffers[n % G_N_ELEMENTS(ds->buffers)]; +} + +static void +ds_set_surfaces(GstVaapiDeinterlaceState *ds) +{ + GstVaapiVideoMeta *meta; + guint i; + + ds->num_surfaces = 0; + for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) { + GstBuffer * const buf = ds_get_buffer(ds, i); + if (!buf) + break; + + meta = gst_buffer_get_vaapi_video_meta(buf); + ds->surfaces[ds->num_surfaces++] = + gst_vaapi_video_meta_get_surface(meta); + } +} + static GstVaapiFilterOpInfo * find_filter_op(GPtrArray *filter_ops, GstVaapiFilterOp op) { @@ -318,6 +367,7 @@ gst_vaapipostproc_destroy_filter(GstVaapiPostproc *postproc) static void gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { + ds_reset(&postproc->deinterlace_state); #if GST_CHECK_VERSION(1,0,0) g_clear_object(&postproc->sinkpad_buffer_pool); #endif @@ -336,6 +386,7 @@ gst_vaapipostproc_start(GstBaseTransform *trans) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + ds_reset(&postproc->deinterlace_state); if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; return TRUE; @@ -346,6 +397,7 @@ gst_vaapipostproc_stop(GstBaseTransform *trans) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); + ds_reset(&postproc->deinterlace_state); gst_vaapi_display_replace(&postproc->display, NULL); return TRUE; } @@ -404,51 +456,6 @@ append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags) 0, -1); } -static void -ds_reset(GstVaapiDeinterlaceState *ds) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) - gst_buffer_replace(&ds->buffers[i], NULL); - ds->buffers_index = 0; - ds->num_surfaces = 0; - ds->deint = FALSE; - ds->tff = FALSE; -} - -static void -ds_add_buffer(GstVaapiDeinterlaceState *ds, GstBuffer *buf) -{ - gst_buffer_replace(&ds->buffers[ds->buffers_index], buf); - ds->buffers_index = (ds->buffers_index + 1) % G_N_ELEMENTS(ds->buffers); -} - -static inline GstBuffer * -ds_get_buffer(GstVaapiDeinterlaceState *ds, guint index) -{ - const guint n = ds->buffers_index + G_N_ELEMENTS(ds->buffers) - index - 1; - return ds->buffers[n % G_N_ELEMENTS(ds->buffers)]; -} - -static void -ds_set_surfaces(GstVaapiDeinterlaceState *ds) -{ - GstVaapiVideoMeta *meta; - guint i; - - ds->num_surfaces = 0; - for (i = 0; i < G_N_ELEMENTS(ds->buffers); i++) { - GstBuffer * const buf = ds_get_buffer(ds, i); - if (!buf) - break; - - meta = gst_buffer_get_vaapi_video_meta(buf); - ds->surfaces[ds->num_surfaces++] = - gst_vaapi_video_meta_get_surface(meta); - } -} - static GstVaapiDeinterlaceMethod get_next_deint_method(GstVaapiDeinterlaceMethod deint_method) { -- 2.7.4