mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +00:00
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().
This commit is contained in:
parent
7e1574b061
commit
98ac557e87
1 changed files with 52 additions and 45 deletions
|
@ -189,6 +189,55 @@ gst_vaapi_deinterlace_mode_get_type(void)
|
||||||
return deinterlace_mode_type;
|
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 *
|
static GstVaapiFilterOpInfo *
|
||||||
find_filter_op(GPtrArray *filter_ops, GstVaapiFilterOp op)
|
find_filter_op(GPtrArray *filter_ops, GstVaapiFilterOp op)
|
||||||
{
|
{
|
||||||
|
@ -318,6 +367,7 @@ gst_vaapipostproc_destroy_filter(GstVaapiPostproc *postproc)
|
||||||
static void
|
static void
|
||||||
gst_vaapipostproc_destroy(GstVaapiPostproc *postproc)
|
gst_vaapipostproc_destroy(GstVaapiPostproc *postproc)
|
||||||
{
|
{
|
||||||
|
ds_reset(&postproc->deinterlace_state);
|
||||||
#if GST_CHECK_VERSION(1,0,0)
|
#if GST_CHECK_VERSION(1,0,0)
|
||||||
g_clear_object(&postproc->sinkpad_buffer_pool);
|
g_clear_object(&postproc->sinkpad_buffer_pool);
|
||||||
#endif
|
#endif
|
||||||
|
@ -336,6 +386,7 @@ gst_vaapipostproc_start(GstBaseTransform *trans)
|
||||||
{
|
{
|
||||||
GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans);
|
GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans);
|
||||||
|
|
||||||
|
ds_reset(&postproc->deinterlace_state);
|
||||||
if (!gst_vaapipostproc_ensure_display(postproc))
|
if (!gst_vaapipostproc_ensure_display(postproc))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -346,6 +397,7 @@ gst_vaapipostproc_stop(GstBaseTransform *trans)
|
||||||
{
|
{
|
||||||
GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans);
|
GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans);
|
||||||
|
|
||||||
|
ds_reset(&postproc->deinterlace_state);
|
||||||
gst_vaapi_display_replace(&postproc->display, NULL);
|
gst_vaapi_display_replace(&postproc->display, NULL);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -404,51 +456,6 @@ append_output_buffer_metadata(GstBuffer *outbuf, GstBuffer *inbuf, guint flags)
|
||||||
0, -1);
|
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
|
static GstVaapiDeinterlaceMethod
|
||||||
get_next_deint_method(GstVaapiDeinterlaceMethod deint_method)
|
get_next_deint_method(GstVaapiDeinterlaceMethod deint_method)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue