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
Unified · Split
| @@ -185,17 +185,20 @@ static void dprintf_link(void *ctx, AVFilterLink *link, int end) · 184 unmodified lines | ||
| 185 | 185 | |
| 186 | 186 | #define DPRINTF_START(ctx, func) dprintf(NULL, "%-16s: ", #func) |
| 187 | 187 | |
| 188 | −AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms) | |
| 188 | +AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h) | |
| 189 | 189 | { |
| 190 | 190 | AVFilterPicRef *ret = NULL; |
| 191 | 191 | |
| 192 | − DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " perms:%d\n", perms); | |
| 192 | + DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " perms:%d w:%d h:%d\n", perms, w, h); | |
| 193 | 193 | |
| 194 | 194 | if(link_dpad(link).get_video_buffer) |
| 195 | − ret = link_dpad(link).get_video_buffer(link, perms); | |
| 195 | + ret = link_dpad(link).get_video_buffer(link, perms, w, h); | |
| 196 | + | |
| 197 | + if(!ret && link->dst->output_count) | |
| 198 | + ret = avfilter_get_video_buffer(link->dst->outputs[0], perms, w, h); | |
| 196 | 199 | |
| 197 | 200 | if(!ret) |
| 198 | − ret = avfilter_default_get_video_buffer(link, perms); | |
| 201 | + ret = avfilter_default_get_video_buffer(link, perms, w, h); | |
| 199 | 202 | |
| 200 | 203 | DPRINTF_START(NULL, get_video_buffer); dprintf_link(NULL, link, 0); dprintf(NULL, " returning "); dprintf_picref(NULL, ret, 1); |
| 201 | 204 | |
| @@ -251,7 +254,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref) · 49 unmodified lines | ||
| 251 | 254 | link_dpad(link).min_perms, link_dpad(link).rej_perms); |
| 252 | 255 | */ |
| 253 | 256 | |
| 254 | − link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms); | |
| 257 | + link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms, link->w, link->h); | |
| 255 | 258 | link->srcpic = picref; |
| 256 | 259 | link->cur_pic->pts = link->srcpic->pts; |
| 257 | 260 | link->cur_pic->pixel_aspect = link->srcpic->pixel_aspect; |
| @@ -22,9 +22,9 @@ · 21 unmodified lines | ||
| 22 | 22 | #ifndef AVFILTER_AVFILTER_H |
| 23 | 23 | #define AVFILTER_AVFILTER_H |
| 24 | 24 | |
| 25 | −#define LIBAVFILTER_VERSION_MAJOR 0 | |
| 26 | −#define LIBAVFILTER_VERSION_MINOR 5 | |
| 27 | −#define LIBAVFILTER_VERSION_MICRO 1 | |
| 25 | +#define LIBAVFILTER_VERSION_MAJOR 1 | |
| 26 | +#define LIBAVFILTER_VERSION_MINOR 0 | |
| 27 | +#define LIBAVFILTER_VERSION_MICRO 0 | |
| 28 | 28 | |
| 29 | 29 | #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
| 30 | 30 | LIBAVFILTER_VERSION_MINOR, \ |
| @@ -293,7 +293,7 @@ struct AVFilterPad · 262 unmodified lines | ||
| 293 | 293 | * |
| 294 | 294 | * Input video pads only. |
| 295 | 295 | */ |
| 296 | − AVFilterPicRef *(*get_video_buffer)(AVFilterLink *link, int perms); | |
| 296 | + AVFilterPicRef *(*get_video_buffer)(AVFilterLink *link, int perms, int w, int h); | |
| 297 | 297 | |
| 298 | 298 | /** |
| 299 | 299 | * Callback called after the slices of a frame are completely sent. If |
| @@ -361,7 +361,7 @@ int avfilter_default_config_output_link(AVFilterLink *link); · 61 unmodified lines | ||
| 361 | 361 | int avfilter_default_config_input_link (AVFilterLink *link); |
| 362 | 362 | /** default handler for get_video_buffer() for video inputs */ |
| 363 | 363 | AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, |
| 364 | − int perms); | |
| 364 | + int perms, int w, int h); | |
| 365 | 365 | /** |
| 366 | 366 | * A helper for query_formats() which sets all links to the same list of |
| 367 | 367 | * 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); · 131 unmodified lines | ||
| 499 | 499 | * @param link the output link to the filter from which the picture will |
| 500 | 500 | * be requested |
| 501 | 501 | * @param perms the required access permissions |
| 502 | + * @param w the minimum width of the buffer to allocate | |
| 503 | + * @param h the minimum height of the buffer to allocate | |
| 502 | 504 | * @return A reference to the picture. This must be unreferenced with |
| 503 | 505 | * avfilter_unref_pic when you are finished with it. |
| 504 | 506 | */ |
| 505 | −AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms); | |
| 507 | +AVFilterPicRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, | |
| 508 | + int w, int h); | |
| 506 | 509 | |
| 507 | 510 | /** |
| 508 | 511 | * Requests an input frame from the filter at the other end of the link. |
| @@ -32,7 +32,7 @@ void avfilter_default_free_video_buffer(AVFilterPic *pic) · 31 unmodified lines | ||
| 32 | 32 | /* TODO: set the buffer's priv member to a context structure for the whole |
| 33 | 33 | * filter chain. This will allow for a buffer pool instead of the constant |
| 34 | 34 | * alloc & free cycle currently implemented. */ |
| 35 | −AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms) | |
| 35 | +AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h) | |
| 36 | 36 | { |
| 37 | 37 | AVFilterPic *pic = av_mallocz(sizeof(AVFilterPic)); |
| 38 | 38 | AVFilterPicRef *ref = av_mallocz(sizeof(AVFilterPicRef)); |
| @@ -40,8 +40,8 @@ AVFilterPicRef *avfilter_default_get_video_buffer(AVFilterLink *link, int perms) · 1 unmodified line | ||
| 40 | 40 | char *buf; |
| 41 | 41 | |
| 42 | 42 | ref->pic = pic; |
| 43 | − ref->w = pic->w = link->w; | |
| 44 | − ref->h = pic->h = link->h; | |
| 43 | + ref->w = pic->w = w; | |
| 44 | + ref->h = pic->h = h; | |
| 45 | 45 | |
| 46 | 46 | /* make sure the buffer gets read permission or it's useless for output */ |
| 47 | 47 | ref->perms = perms | AV_PERM_READ; |
| @@ -72,7 +72,7 @@ void avfilter_default_start_frame(AVFilterLink *link, AVFilterPicRef *picref) · 24 unmodified lines | ||
| 72 | 72 | out = link->dst->outputs[0]; |
| 73 | 73 | |
| 74 | 74 | if(out) { |
| 75 | − out->outpic = avfilter_get_video_buffer(out, AV_PERM_WRITE); | |
| 75 | + out->outpic = avfilter_get_video_buffer(out, AV_PERM_WRITE, link->w, link->h); | |
| 76 | 76 | out->outpic->pts = picref->pts; |
| 77 | 77 | avfilter_start_frame(out, avfilter_ref_pic(out->outpic, ~0)); |
| 78 | 78 | } |