From 0eb4ff9e37f2b44bcf143c9b503609cea5db13cb Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sun, 18 Oct 2009 08:16:18 +0000 Subject: [PATCH] Make avfilter_get_video_buffer() recursive. When called on a link with a filter whose destination pad has not a get_video_buffer callback defined, it will call avfilter_get_video_buffer() on the first output link of the destination filer, rather than use avfilter_default_get_buffer(), so the video buffer can be allocated forward in the filterchain. Also add the w and h parameters to avfilter_get_video_buffer(), as the minimum width and height requested by each filter in the filterchain may change, this allows for example a memcpy-less pad filter. This change breaks API / ABI backward compatibility. See the thread: "[PATCH] Implement recusive avfilter_get_video_buffer()". Originally committed as revision 20272 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavfilter/avfilter.c | 13 ++++++++----- libavfilter/avfilter.h | 15 +++++++++------ libavfilter/defaults.c | 8 ++++---- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 60880779ff..77c7571388 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -185,17 +185,20 @@ static void dprintf_link(void *ctx, AVFilterLink *link, int end) #define DPRINTF_START(ctx, func) dprintf(NULL, "%-16s: ", #func) -AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms) +AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h) { AVFilterPicRef *ret = NULL; - DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " perms:%d\n", perms); + DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " perms:%d w:%d h:%d\n", perms, w, h); if(link_dpad(link).get_video_buffer) - ret = link_dpad(link).get_video_buffer(link, perms); + ret = link_dpad(link).get_video_buffer(link, perms, w, h); + + if(!ret && link->dst->output_count) + ret = avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h); if(!ret) - ret = avfilter_default_get_video_buffer(link, perms); + ret = avfilter_default_get_video_buffer(link, perms, w, h); DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " returning "); dprintf_picref(NULL, ret, 1); @@ -251,7 +254,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref) link_dpad(link).min_perms, link_dpad(link).rej_perms); */ - link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms); + link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms, link->w, link->h); link->srcpic = picref; link->cur_pic->pts = link->srcpic->pts; link->cur_pic->pixel_aspect = link->srcpic->pixel_aspect; diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 9c282e278c..2b17dea2a6 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -22,9 +22,9 @@ #ifndef AVFILTER_AVFILTER_H #define AVFILTER_AVFILTER_H -#define LIBAVFILTER_VERSION_MAJOR 0 -#define LIBAVFILTER_VERSION_MINOR 5 -#define LIBAVFILTER_VERSION_MICRO 1 +#define LIBAVFILTER_VERSION_MAJOR 1 +#define LIBAVFILTER_VERSION_MINOR 0 +#define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ @@ -293,7 +293,7 @@ struct AVFilterPad * * Input video pads only. */ - AVFilterPicRef *(*get_video_buffer)(AVFilterLink *link, int perms); + AVFilterPicRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h); /** * Callback called after the slices of a frame are completely sent. If @@ -361,7 +361,7 @@ int avfilter_default_config_output_link(AVFilterLink *link); int avfilter_default_config_input_link (AVFilterLink *link); /** default handler for get_video_buffer() for video inputs */ AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, - int perms); + int perms, int w, int h); /** * A helper for query_formats() which sets all links to the same list of * formats. If there are no links hooked to this filter, the list of formats is @@ -499,10 +499,13 @@ int avfilter_config_links(AVFilterContext *filter); * @param link the output link to the filter from which the picture will * be requested * @param perms the required access permissions + * @param w the minimum width of the buffer to allocate + * @param h the minimum height of the buffer to allocate * @return A reference to the picture. This must be unreferenced with * avfilter_unref_pic when you are finished with it. */ -AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms); +AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, + int w, int h); /** * Requests an input frame from the filter at the other end of the link. diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c index dabb1d5bf0..1983672cd6 100644 --- a/libavfilter/defaults.c +++ b/libavfilter/defaults.c @@ -32,7 +32,7 @@ void avfilter_default_free_video_buffer(AVFilterPic *pic) /* TODO: set the buffer's priv member to a context structure for the whole * filter chain. This will allow for a buffer pool instead of the constant * alloc & free cycle currently implemented. */ -AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms) +AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h) { AVFilterPic *pic = av_mallocz(sizeof(AVFilterPic)); AVFilterPicRef *ref = av_mallocz(sizeof(AVFilterPicRef)); @@ -40,8 +40,8 @@ AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms) char *buf; ref->pic = pic; - ref->w = pic->w = link->w; - ref->h = pic->h = link->h; + ref->w = pic->w = w; + ref->h = pic->h = h; /* make sure the buffer gets read permission or it's useless for output */ ref->perms = perms | AV_PERM_READ; @@ -72,7 +72,7 @@ void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref) out = link->dst->outputs[0]; if(out) { - out->outpic = avfilter_get_video_buffer(out, AV_PERM_WRITE); + out->outpic = avfilter_get_video_buffer(out, AV_PERM_WRITE, link->w, link->h); out->outpic->pts = picref->pts; avfilter_start_frame(out, avfilter_ref_pic(out->outpic, ~0)); } -- GitLab