OSDN Git Service

lavfi: create buffer reference in filters which need to access the ref later
authorStefano Sabatini <stefasab@gmail.com>
Tue, 24 Apr 2012 22:25:18 +0000 (00:25 +0200)
committerStefano Sabatini <stefasab@gmail.com>
Fri, 27 Apr 2012 19:38:13 +0000 (21:38 +0200)
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
libavfilter/vf_bbox.c
libavfilter/vf_blackdetect.c
libavfilter/vf_blackframe.c
libavfilter/vf_showinfo.c

index 47d7351..e8516c3 100644 (file)
@@ -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 */
index f3d62fb..f8dc625 100644 (file)
@@ -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 }
index db94794..ea45f05 100644 (file)
@@ -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 }
     },
index d57092d..7e80fd7 100644 (file)
@@ -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}},
 
index 657e6e6..ece6230 100644 (file)
@@ -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}},