From 6b55aab01a5c2e4c9f2851fdb9b7583f184b5241 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Wed, 25 Apr 2012 00:25:18 +0200 Subject: [PATCH] lavfi: create buffer reference in filters which need to access the ref later Also add internal function ff_null_start_frame_keep_ref(). Fix crash when a following filter (e.g. settb) will unref the reference passed by start_frame(), and then the reference is accessed in end_frame() through inlink->cur_buf. --- libavfilter/internal.h | 9 +++++++++ libavfilter/vf_bbox.c | 4 +++- libavfilter/vf_blackdetect.c | 3 ++- libavfilter/vf_blackframe.c | 4 +++- libavfilter/vf_showinfo.c | 4 +++- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 47d735182d..e8516c3ba1 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -140,4 +140,13 @@ int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx); */ int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx); +/** + * Pass video frame along and keep an internal reference for later use. + */ +static inline void ff_null_start_frame_keep_ref(AVFilterLink *inlink, + AVFilterBufferRef *picref) +{ + avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); +} + #endif /* AVFILTER_INTERNAL_H */ diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c index f3d62fb16a..f8dc625524 100644 --- a/libavfilter/vf_bbox.c +++ b/libavfilter/vf_bbox.c @@ -27,6 +27,7 @@ #include "libavutil/timestamp.h" #include "avfilter.h" #include "bbox.h" +#include "internal.h" typedef struct { unsigned int frame; @@ -85,6 +86,7 @@ static void end_frame(AVFilterLink *inlink) av_log(ctx, AV_LOG_INFO, "\n"); bbox->frame++; + avfilter_unref_buffer(picref); avfilter_end_frame(inlink->dst->outputs[0]); } @@ -99,7 +101,7 @@ AVFilter avfilter_vf_bbox = { { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .get_video_buffer = avfilter_null_get_video_buffer, - .start_frame = avfilter_null_start_frame, + .start_frame = ff_null_start_frame_keep_ref, .end_frame = end_frame, .min_perms = AV_PERM_READ, }, { .name = NULL } diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c index db94794979..ea45f0522e 100644 --- a/libavfilter/vf_blackdetect.c +++ b/libavfilter/vf_blackdetect.c @@ -180,6 +180,7 @@ static void end_frame(AVFilterLink *inlink) blackdetect->frame_count++; blackdetect->nb_black_pixels = 0; + avfilter_unref_buffer(picref); avfilter_end_frame(inlink->dst->outputs[0]); } @@ -196,7 +197,7 @@ AVFilter avfilter_vf_blackdetect = { .config_props = config_input, .draw_slice = draw_slice, .get_video_buffer = avfilter_null_get_video_buffer, - .start_frame = avfilter_null_start_frame, + .start_frame = ff_null_start_frame_keep_ref, .end_frame = end_frame, }, { .name = NULL } }, diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index d57092ddf2..7e80fd7e46 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -28,6 +28,7 @@ */ #include "avfilter.h" +#include "internal.h" typedef struct { unsigned int bamount; ///< black amount @@ -110,6 +111,7 @@ static void end_frame(AVFilterLink *inlink) blackframe->frame++; blackframe->nblack = 0; + avfilter_unref_buffer(picref); avfilter_end_frame(inlink->dst->outputs[0]); } @@ -126,7 +128,7 @@ AVFilter avfilter_vf_blackframe = { .type = AVMEDIA_TYPE_VIDEO, .draw_slice = draw_slice, .get_video_buffer = avfilter_null_get_video_buffer, - .start_frame = avfilter_null_start_frame, + .start_frame = ff_null_start_frame_keep_ref, .end_frame = end_frame, }, { .name = NULL}}, diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index 657e6e6df2..ece6230877 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -27,6 +27,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/timestamp.h" #include "avfilter.h" +#include "internal.h" typedef struct { unsigned int frame; @@ -79,6 +80,7 @@ static void end_frame(AVFilterLink *inlink) av_log(ctx, AV_LOG_INFO, "]\n"); showinfo->frame++; + avfilter_unref_buffer(picref); avfilter_end_frame(inlink->dst->outputs[0]); } @@ -92,7 +94,7 @@ AVFilter avfilter_vf_showinfo = { .inputs = (const AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, .get_video_buffer = avfilter_null_get_video_buffer, - .start_frame = avfilter_null_start_frame, + .start_frame = ff_null_start_frame_keep_ref, .end_frame = end_frame, .min_perms = AV_PERM_READ, }, { .name = NULL}},