[FFmpeg-devel] [PATCH] lavfi: create reference in filters which needs to access the ref later

Stefano Sabatini stefasab at gmail.com
Wed Apr 25 00:35:02 CEST 2012


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/vf_bbox.c        |    8 +++++++-
 libavfilter/vf_blackdetect.c |    8 +++++++-
 libavfilter/vf_blackframe.c  |    8 +++++++-
 libavfilter/vf_showinfo.c    |    8 +++++++-
 4 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c
index f3d62fb..b01903e 100644
--- a/libavfilter/vf_bbox.c
+++ b/libavfilter/vf_bbox.c
@@ -55,6 +55,11 @@ static int query_formats(AVFilterContext *ctx)
     return 0;
 }
 
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+    avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
+}
+
 static void end_frame(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
@@ -85,6 +90,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 +105,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      = start_frame,
           .end_frame        = end_frame,
           .min_perms        = AV_PERM_READ, },
         { .name = NULL }
diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c
index db94794..44ed47e 100644
--- a/libavfilter/vf_blackdetect.c
+++ b/libavfilter/vf_blackdetect.c
@@ -125,6 +125,11 @@ static int config_input(AVFilterLink *inlink)
     return 0;
 }
 
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+    avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
+}
+
 static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
 {
     AVFilterContext *ctx = inlink->dst;
@@ -180,6 +185,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 +202,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      = start_frame,
           .end_frame        = end_frame, },
         { .name = NULL }
     },
diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c
index d57092d..f396c3f 100644
--- a/libavfilter/vf_blackframe.c
+++ b/libavfilter/vf_blackframe.c
@@ -73,6 +73,11 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
     return 0;
 }
 
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+    avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
+}
+
 static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
 {
     AVFilterContext *ctx = inlink->dst;
@@ -110,6 +115,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 +132,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      = start_frame,
                                     .end_frame        = end_frame, },
                                   { .name = NULL}},
 
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index 657e6e6..80e8d1c 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -39,6 +39,11 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
     return 0;
 }
 
+static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+    avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0));
+}
+
 static void end_frame(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
@@ -79,6 +84,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 +98,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      = start_frame,
                                     .end_frame        = end_frame,
                                     .min_perms        = AV_PERM_READ, },
                                   { .name = NULL}},
-- 
1.7.5.4



More information about the ffmpeg-devel mailing list