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.
pull/30/merge
Stefano Sabatini 13 years ago
parent 6f3b1d7f86
commit 6b55aab01a
  1. 9
      libavfilter/internal.h
  2. 4
      libavfilter/vf_bbox.c
  3. 3
      libavfilter/vf_blackdetect.c
  4. 4
      libavfilter/vf_blackframe.c
  5. 4
      libavfilter/vf_showinfo.c

@ -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); 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 */ #endif /* AVFILTER_INTERNAL_H */

@ -27,6 +27,7 @@
#include "libavutil/timestamp.h" #include "libavutil/timestamp.h"
#include "avfilter.h" #include "avfilter.h"
#include "bbox.h" #include "bbox.h"
#include "internal.h"
typedef struct { typedef struct {
unsigned int frame; unsigned int frame;
@ -85,6 +86,7 @@ static void end_frame(AVFilterLink *inlink)
av_log(ctx, AV_LOG_INFO, "\n"); av_log(ctx, AV_LOG_INFO, "\n");
bbox->frame++; bbox->frame++;
avfilter_unref_buffer(picref);
avfilter_end_frame(inlink->dst->outputs[0]); avfilter_end_frame(inlink->dst->outputs[0]);
} }
@ -99,7 +101,7 @@ AVFilter avfilter_vf_bbox = {
{ .name = "default", { .name = "default",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer = avfilter_null_get_video_buffer, .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, .end_frame = end_frame,
.min_perms = AV_PERM_READ, }, .min_perms = AV_PERM_READ, },
{ .name = NULL } { .name = NULL }

@ -180,6 +180,7 @@ static void end_frame(AVFilterLink *inlink)
blackdetect->frame_count++; blackdetect->frame_count++;
blackdetect->nb_black_pixels = 0; blackdetect->nb_black_pixels = 0;
avfilter_unref_buffer(picref);
avfilter_end_frame(inlink->dst->outputs[0]); avfilter_end_frame(inlink->dst->outputs[0]);
} }
@ -196,7 +197,7 @@ AVFilter avfilter_vf_blackdetect = {
.config_props = config_input, .config_props = config_input,
.draw_slice = draw_slice, .draw_slice = draw_slice,
.get_video_buffer = avfilter_null_get_video_buffer, .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, }, .end_frame = end_frame, },
{ .name = NULL } { .name = NULL }
}, },

@ -28,6 +28,7 @@
*/ */
#include "avfilter.h" #include "avfilter.h"
#include "internal.h"
typedef struct { typedef struct {
unsigned int bamount; ///< black amount unsigned int bamount; ///< black amount
@ -110,6 +111,7 @@ static void end_frame(AVFilterLink *inlink)
blackframe->frame++; blackframe->frame++;
blackframe->nblack = 0; blackframe->nblack = 0;
avfilter_unref_buffer(picref);
avfilter_end_frame(inlink->dst->outputs[0]); avfilter_end_frame(inlink->dst->outputs[0]);
} }
@ -126,7 +128,7 @@ AVFilter avfilter_vf_blackframe = {
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.draw_slice = draw_slice, .draw_slice = draw_slice,
.get_video_buffer = avfilter_null_get_video_buffer, .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, }, .end_frame = end_frame, },
{ .name = NULL}}, { .name = NULL}},

@ -27,6 +27,7 @@
#include "libavutil/pixdesc.h" #include "libavutil/pixdesc.h"
#include "libavutil/timestamp.h" #include "libavutil/timestamp.h"
#include "avfilter.h" #include "avfilter.h"
#include "internal.h"
typedef struct { typedef struct {
unsigned int frame; unsigned int frame;
@ -79,6 +80,7 @@ static void end_frame(AVFilterLink *inlink)
av_log(ctx, AV_LOG_INFO, "]\n"); av_log(ctx, AV_LOG_INFO, "]\n");
showinfo->frame++; showinfo->frame++;
avfilter_unref_buffer(picref);
avfilter_end_frame(inlink->dst->outputs[0]); avfilter_end_frame(inlink->dst->outputs[0]);
} }
@ -92,7 +94,7 @@ AVFilter avfilter_vf_showinfo = {
.inputs = (const AVFilterPad[]) {{ .name = "default", .inputs = (const AVFilterPad[]) {{ .name = "default",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.get_video_buffer = avfilter_null_get_video_buffer, .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, .end_frame = end_frame,
.min_perms = AV_PERM_READ, }, .min_perms = AV_PERM_READ, },
{ .name = NULL}}, { .name = NULL}},

Loading…
Cancel
Save