[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