diff options
Diffstat (limited to 'libavfilter/video.c')
-rw-r--r-- | libavfilter/video.c | 100 |
1 files changed, 63 insertions, 37 deletions
diff --git a/libavfilter/video.c b/libavfilter/video.c index 0eed22129a..92b16b2b53 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -149,13 +149,15 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int return ret; } -void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~0); - ff_start_frame(link->dst->outputs[0], buf_out); + if (!buf_out) + return AVERROR(ENOMEM); + return ff_start_frame(link->dst->outputs[0], buf_out); } -static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterLink *outlink = NULL; @@ -163,21 +165,37 @@ static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) outlink = inlink->dst->outputs[0]; if (outlink) { + AVFilterBufferRef *buf_out; outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + if (!outlink->out_buf) + return AVERROR(ENOMEM); + avfilter_copy_buffer_ref_props(outlink->out_buf, picref); outlink->out_buf->video->w = outlink->w; outlink->out_buf->video->h = outlink->h; - ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); + buf_out = avfilter_ref_buffer(outlink->out_buf, ~0); + if (!buf_out) + return AVERROR(ENOMEM); + + return ff_start_frame(outlink, buf_out); } + return 0; +} + +static void clear_link(AVFilterLink *link) +{ + avfilter_unref_bufferp(&link->cur_buf); + avfilter_unref_bufferp(&link->src_buf); + avfilter_unref_bufferp(&link->out_buf); } /* XXX: should we do the duplicating of the picture ref here, instead of * forcing the source filter to do it? */ -void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { - void (*start_frame)(AVFilterLink *, AVFilterBufferRef *); + int (*start_frame)(AVFilterLink *, AVFilterBufferRef *); AVFilterPad *dst = link->dstpad; - int perms = picref->perms; + int ret, perms = picref->perms; AVFilterCommand *cmd= link->dst->command_queue; int64_t pts; @@ -196,6 +214,11 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) link->dstpad->min_perms, link->dstpad->rej_perms); link->cur_buf = ff_get_video_buffer(link, dst->min_perms, link->w, link->h); + if (!link->cur_buf) { + avfilter_unref_bufferp(&picref); + return AVERROR(ENOMEM); + } + link->src_buf = picref; avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf); @@ -215,22 +238,26 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) cmd= link->dst->command_queue; } pts = link->cur_buf->pts; - start_frame(link, link->cur_buf); + ret = start_frame(link, link->cur_buf); ff_update_link_current_pts(link,link->cur_buf ? link->cur_buf->pts : pts); + if (ret < 0) + clear_link(link); + + return ret; } -void ff_null_start_frame_keep_ref(AVFilterLink *inlink, +int ff_null_start_frame_keep_ref(AVFilterLink *inlink, AVFilterBufferRef *picref) { - ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); + return ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); } -void ff_null_end_frame(AVFilterLink *link) +int ff_null_end_frame(AVFilterLink *link) { - ff_end_frame(link->dst->outputs[0]); + return ff_end_frame(link->dst->outputs[0]); } -static void default_end_frame(AVFilterLink *inlink) +static int default_end_frame(AVFilterLink *inlink) { AVFilterLink *outlink = NULL; @@ -238,37 +265,32 @@ static void default_end_frame(AVFilterLink *inlink) outlink = inlink->dst->outputs[0]; if (outlink) { - ff_end_frame(outlink); + return ff_end_frame(outlink); } + return 0; } -void ff_end_frame(AVFilterLink *link) +int ff_end_frame(AVFilterLink *link) { - void (*end_frame)(AVFilterLink *); + int (*end_frame)(AVFilterLink *); + int ret; if (!(end_frame = link->dstpad->end_frame)) end_frame = default_end_frame; - end_frame(link); + ret = end_frame(link); - /* unreference the source picture if we're feeding the destination filter - * a copied version dues to permission issues */ - if (link->src_buf) { - avfilter_unref_buffer(link->src_buf); - link->src_buf = NULL; - } - if(link->cur_buf != link->out_buf) - avfilter_unref_bufferp(&link->cur_buf); - link->cur_buf = NULL; - avfilter_unref_bufferp(&link->out_buf); + clear_link(link); + + return ret; } -void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { - ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); + return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); } -static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterLink *outlink = NULL; @@ -276,14 +298,15 @@ static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir outlink = inlink->dst->outputs[0]; if (outlink) - ff_draw_slice(outlink, y, h, slice_dir); + return ff_draw_slice(outlink, y, h, slice_dir); + return 0; } -void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +int ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { uint8_t *src[4], *dst[4]; - int i, j, vsub; - void (*draw_slice)(AVFilterLink *, int, int, int); + int i, j, vsub, ret; + int (*draw_slice)(AVFilterLink *, int, int, int); FF_TPRINTF_START(NULL, draw_slice); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir); @@ -317,11 +340,14 @@ void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) if (!(draw_slice = link->dstpad->draw_slice)) draw_slice = default_draw_slice; - draw_slice(link, y, h, slice_dir); + ret = draw_slice(link, y, h, slice_dir); + if (ret < 0) + clear_link(link); + return ret; } -void avfilter_default_end_frame(AVFilterLink *inlink) +int avfilter_default_end_frame(AVFilterLink *inlink) { - default_end_frame(inlink); + return default_end_frame(inlink); } |