From ebc8d974817fe456a0afe6867fdeb22c761fb04f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 8 Jul 2012 17:29:42 +0200 Subject: [PATCH 01/16] lavfi: add error handling to start_frame(). --- libavfilter/avfilter.h | 5 +++- libavfilter/buffersink.c | 10 +++----- libavfilter/fifo.c | 9 ++----- libavfilter/internal.h | 3 +++ libavfilter/split.c | 14 +++++++---- libavfilter/vf_aspect.c | 4 +-- libavfilter/vf_crop.c | 7 ++++-- libavfilter/vf_delogo.c | 21 +++++++++++++--- libavfilter/vf_drawtext.c | 16 ++++++------ libavfilter/vf_fieldorder.c | 20 ++++++++++++--- libavfilter/vf_fps.c | 3 ++- libavfilter/vf_gradfun.c | 21 +++++++++++++--- libavfilter/vf_overlay.c | 7 +++--- libavfilter/vf_pad.c | 28 +++++++++++++++++---- libavfilter/vf_pixdesctest.c | 21 +++++++++++----- libavfilter/vf_scale.c | 19 +++++++++++---- libavfilter/vf_select.c | 8 +++--- libavfilter/vf_setpts.c | 7 ++++-- libavfilter/vf_settb.c | 4 +-- libavfilter/vf_slicify.c | 4 +-- libavfilter/vf_transpose.c | 7 ++++-- libavfilter/vf_vflip.c | 4 +-- libavfilter/vf_yadif.c | 9 +++---- libavfilter/video.c | 47 ++++++++++++++++++++++++------------ libavfilter/video.h | 7 ++++-- libavfilter/vsink_nullsink.c | 3 ++- 26 files changed, 209 insertions(+), 99 deletions(-) diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 7fbdd8a2fb..a685761cfb 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -258,8 +258,11 @@ struct AVFilterPad { * picture inside the link structure. * * Input video pads only. + * + * @return >= 0 on success, a negative AVERROR on error. picref will be + * unreferenced by the caller in case of error. */ - void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); + int (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); /** * Callback function to get a video buffer. If NULL, the filter system will diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 76a0585ee1..04320b5654 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -47,20 +47,16 @@ static av_cold void uninit(AVFilterContext *ctx) av_audio_fifo_free(sink->audio_fifo); } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *buf) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *buf) { BufferSinkContext *s = link->dst->priv; av_assert0(!s->cur_buf); s->cur_buf = buf; link->cur_buf = NULL; -}; -static int filter_samples(AVFilterLink *link, AVFilterBufferRef *buf) -{ - start_frame(link, buf); return 0; -} +}; int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf) { @@ -166,7 +162,7 @@ AVFilter avfilter_asink_abuffer = { .inputs = (const AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_AUDIO, - .filter_samples = filter_samples, + .filter_samples = start_frame, .min_perms = AV_PERM_READ, .needs_fifo = 1 }, { .name = NULL }}, diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index cbe1e5ef73..185960ebc7 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -76,6 +76,7 @@ static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf) { FifoContext *fifo = inlink->dst->priv; + inlink->cur_buf = NULL; fifo->last->next = av_mallocz(sizeof(Buf)); if (!fifo->last->next) { avfilter_unref_buffer(buf); @@ -88,12 +89,6 @@ static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *buf) -{ - add_to_queue(inlink, buf); - inlink->cur_buf = NULL; -} - static void queue_pop(FifoContext *s) { Buf *tmp = s->root.next->next; @@ -272,7 +267,7 @@ AVFilter avfilter_vf_fifo = { .inputs = (const AVFilterPad[]) {{ .name = "default", .type = AVMEDIA_TYPE_VIDEO, .get_video_buffer= ff_null_get_video_buffer, - .start_frame = start_frame, + .start_frame = add_to_queue, .draw_slice = draw_slice, .end_frame = end_frame, .rej_perms = AV_PERM_REUSE2, }, diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 26059c927b..c08e00bcb8 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -69,6 +69,9 @@ struct AVFilterPad { * picture inside the link structure. * * Input video pads only. + * + * @return >= 0 on success, a negative AVERROR on error. picref will be + * unreferenced by the caller in case of error. */ void (*start_frame)(AVFilterLink *link, AVFilterBufferRef *picref); diff --git a/libavfilter/split.c b/libavfilter/split.c index ea610f3cb3..5ffbc856f6 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -63,14 +63,18 @@ static void split_uninit(AVFilterContext *ctx) av_freep(&ctx->output_pads[i].name); } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterContext *ctx = inlink->dst; - int i; + int i, ret = 0; - for (i = 0; i < ctx->nb_outputs; i++) - ff_start_frame(ctx->outputs[i], - avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); + for (i = 0; i < ctx->nb_outputs; i++) { + ret = ff_start_frame(ctx->outputs[i], + avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); + if (ret < 0) + break; + } + return ret; } static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c index 735f5c080c..8738b0a764 100644 --- a/libavfilter/vf_aspect.c +++ b/libavfilter/vf_aspect.c @@ -64,13 +64,13 @@ static av_cold int init(AVFilterContext *ctx, const char *args) return 0; } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { AspectContext *aspect = link->dst->priv; picref->video->pixel_aspect = aspect->aspect; link->cur_buf = NULL; - ff_start_frame(link->dst->outputs[0], picref); + return ff_start_frame(link->dst->outputs[0], picref); } #if CONFIG_SETDAR_FILTER diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index 14989f8259..636e853259 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -240,7 +240,7 @@ static int config_output(AVFilterLink *link) return 0; } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { AVFilterContext *ctx = link->dst; CropContext *crop = ctx->priv; @@ -248,6 +248,9 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) int i; ref2 = avfilter_ref_buffer(picref, ~0); + if (!ref2) + return AVERROR(ENOMEM); + ref2->video->w = crop->w; ref2->video->h = crop->h; @@ -291,7 +294,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) ref2->data[3] += crop->x * crop->max_step[3]; } - ff_start_frame(link->dst->outputs[0], ref2); + return ff_start_frame(link->dst->outputs[0], ref2); } static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index ffaaa22266..5f8f9ff6ff 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -214,22 +214,35 @@ static av_cold int init(AVFilterContext *ctx, const char *args) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpicref; + AVFilterBufferRef *outpicref = NULL; + int ret = 0; if (inpicref->perms & AV_PERM_PRESERVE) { outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + if (!outpicref) + return AVERROR(ENOMEM); + avfilter_copy_buffer_ref_props(outpicref, inpicref); outpicref->video->w = outlink->w; outpicref->video->h = outlink->h; - } else + } else { outpicref = avfilter_ref_buffer(inpicref, ~0); + if (!outpicref) + return AVERROR(ENOMEM); + } + + ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + if (ret < 0) { + avfilter_unref_bufferp(&outpicref); + return ret; + } outlink->out_buf = outpicref; - ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + return 0; } static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 84aaa5f7aa..f9a92615c9 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -808,16 +808,16 @@ static inline int normalize_double(int *n, double d) return ret; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterContext *ctx = inlink->dst; DrawTextContext *dtext = ctx->priv; AVFilterBufferRef *buf_out; - int fail = 0; + int ret = 0; - if (dtext_prepare_text(ctx) < 0) { + if ((ret = dtext_prepare_text(ctx)) < 0) { av_log(ctx, AV_LOG_ERROR, "Can't draw text\n"); - fail = 1; + return ret; } dtext->var_values[VAR_T] = inpicref->pts == AV_NOPTS_VALUE ? @@ -829,8 +829,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng); - dtext->draw = fail ? 0 : - av_expr_eval(dtext->d_pexpr, dtext->var_values, &dtext->prng); + dtext->draw = av_expr_eval(dtext->d_pexpr, dtext->var_values, &dtext->prng); normalize_double(&dtext->x, dtext->var_values[VAR_X]); normalize_double(&dtext->y, dtext->var_values[VAR_Y]); @@ -852,7 +851,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) dtext->x, dtext->y, dtext->x+dtext->w, dtext->y+dtext->h); buf_out = avfilter_ref_buffer(inpicref, ~0); - ff_start_frame(inlink->dst->outputs[0], buf_out); + if (!buf_out) + return AVERROR(ENOMEM); + + return ff_start_frame(inlink->dst->outputs[0], buf_out); } static void end_frame(AVFilterLink *inlink) diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c index 754cccd885..0a8af75851 100644 --- a/libavfilter/vf_fieldorder.c +++ b/libavfilter/vf_fieldorder.c @@ -116,18 +116,32 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int return ff_get_video_buffer(outlink, perms, w, h); } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; AVFilterBufferRef *outpicref, *for_next_filter; + int ret = 0; outpicref = avfilter_ref_buffer(inpicref, ~0); - outlink->out_buf = outpicref; + if (!outpicref) + return AVERROR(ENOMEM); for_next_filter = avfilter_ref_buffer(outpicref, ~0); - ff_start_frame(outlink, for_next_filter); + if (!for_next_filter) { + avfilter_unref_bufferp(&outpicref); + return AVERROR(ENOMEM); + } + + ret = ff_start_frame(outlink, for_next_filter); + if (ret < 0) { + avfilter_unref_bufferp(&outpicref); + return ret; + } + + outlink->out_buf = outpicref; + return 0; } static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index fbc4d87966..ca0d36630d 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -243,8 +243,9 @@ static void end_frame(AVFilterLink *inlink) s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base); } -static void null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf) +static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf) { + return 0; } static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 4ab0827b56..83186e561e 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -180,21 +180,34 @@ static int config_input(AVFilterLink *inlink) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpicref; + AVFilterBufferRef *outpicref = NULL; + int ret = 0; if (inpicref->perms & AV_PERM_PRESERVE) { outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + if (!outpicref) + return AVERROR(ENOMEM); + avfilter_copy_buffer_ref_props(outpicref, inpicref); outpicref->video->w = outlink->w; outpicref->video->h = outlink->h; - } else + } else { outpicref = avfilter_ref_buffer(inpicref, ~0); + if (!outpicref) + return AVERROR(ENOMEM); + } + + ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + if (ret < 0) { + avfilter_unref_bufferp(&outpicref); + return ret; + } outlink->out_buf = outpicref; - ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + return 0; } static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index d6949d51e5..926e9a205c 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -208,7 +208,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w, return ff_get_video_buffer(link->dst->outputs[0], perms, w, h); } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); AVFilterContext *ctx = inlink->dst; @@ -228,10 +228,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) over->overpicref = old; } - ff_start_frame(inlink->dst->outputs[0], outpicref); + return ff_start_frame(inlink->dst->outputs[0], outpicref); } -static void start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterContext *ctx = inlink->dst; OverlayContext *over = ctx->priv; @@ -239,6 +239,7 @@ static void start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicre over->overpicref = inpicref; over->overpicref->pts = av_rescale_q(inpicref->pts, ctx->inputs[OVERLAY]->time_base, ctx->outputs[0]->time_base); + return 0; } static void blend_slice(AVFilterContext *ctx, diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 9a7f1e0aed..298aae4131 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -299,12 +299,15 @@ static int does_clip(PadContext *pad, AVFilterBufferRef *outpicref, int plane, i return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { PadContext *pad = inlink->dst->priv; AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); AVFilterBufferRef *for_next_filter; - int plane; + int plane, ret = 0; + + if (!outpicref) + return AVERROR(ENOMEM); for (plane = 0; plane < 4 && outpicref->data[plane]; plane++) { int hsub = (plane == 1 || plane == 2) ? pad->hsub : 0; @@ -332,16 +335,31 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref = ff_get_video_buffer(inlink->dst->outputs[0], AV_PERM_WRITE | AV_PERM_NEG_LINESIZES, FFMAX(inlink->w, pad->w), FFMAX(inlink->h, pad->h)); + if (!outpicref) + return AVERROR(ENOMEM); + avfilter_copy_buffer_ref_props(outpicref, inpicref); } - inlink->dst->outputs[0]->out_buf = outpicref; - outpicref->video->w = pad->w; outpicref->video->h = pad->h; for_next_filter = avfilter_ref_buffer(outpicref, ~0); - ff_start_frame(inlink->dst->outputs[0], for_next_filter); + if (!for_next_filter) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = ff_start_frame(inlink->dst->outputs[0], for_next_filter); + if (ret < 0) + goto fail; + + inlink->dst->outputs[0]->out_buf = outpicref; + return 0; + +fail: + avfilter_unref_bufferp(&outpicref); + return ret; } static void end_frame(AVFilterLink *link) diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c index c873105dfb..ae0a5063d2 100644 --- a/libavfilter/vf_pixdesctest.c +++ b/libavfilter/vf_pixdesctest.c @@ -51,16 +51,18 @@ static int config_props(AVFilterLink *inlink) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { PixdescTestContext *priv = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *outpicref; - int i; + int i, ret = 0; + + outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, + outlink->w, outlink->h); + if (!outpicref) + return AVERROR(ENOMEM); - outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, - outlink->w, outlink->h); - outpicref = outlink->out_buf; avfilter_copy_buffer_ref_props(outpicref, picref); for (i = 0; i < 4; i++) { @@ -78,7 +80,14 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) priv->pix_desc->flags & PIX_FMT_PSEUDOPAL) memcpy(outpicref->data[1], outpicref->data[1], 256*4); - ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + if (ret < 0) { + avfilter_unref_bufferp(&outpicref); + return ret; + } + + outlink->out_buf = outpicref; + return 0; } static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index d9d1cf0147..6c5421006b 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -252,26 +252,28 @@ fail: return ret; } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { ScaleContext *scale = link->dst->priv; AVFilterLink *outlink = link->dst->outputs[0]; AVFilterBufferRef *outpicref; + int ret = 0; if (!scale->sws) { - ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); - return; + return ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); } scale->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w; scale->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + if (!outpicref) + return AVERROR(ENOMEM); + avfilter_copy_buffer_ref_props(outpicref, picref); outpicref->video->w = outlink->w; outpicref->video->h = outlink->h; - outlink->out_buf = outpicref; av_reduce(&outpicref->video->pixel_aspect.num, &outpicref->video->pixel_aspect.den, (int64_t)picref->video->pixel_aspect.num * outlink->h * link->w, @@ -279,7 +281,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) INT_MAX); scale->slice_y = 0; - ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + if (ret < 0) { + avfilter_unref_bufferp(&outpicref); + return ret; + } + + outlink->out_buf = outpicref; + return 0; } static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index 8f47b4144a..8b3a6f84a5 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -227,7 +227,7 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref) return res; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { SelectContext *select = inlink->dst->priv; @@ -241,10 +241,12 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) else av_fifo_generic_write(select->pending_frames, &picref, sizeof(picref), NULL); - return; + return 0; } - 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)); } + + return 0; } static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c index a0d60a5b07..c4339b202a 100644 --- a/libavfilter/vf_setpts.c +++ b/libavfilter/vf_setpts.c @@ -101,12 +101,15 @@ static int config_input(AVFilterLink *inlink) #define D2TS(d) (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d)) #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)) -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { SetPTSContext *setpts = inlink->dst->priv; double d; AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); + if (!outpicref) + return AVERROR(ENOMEM); + if (isnan(setpts->var_values[VAR_STARTPTS])) setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts); @@ -130,7 +133,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) setpts->var_values[VAR_N] += 1.0; setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts); setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts); - ff_start_frame(inlink->dst->outputs[0], outpicref); + return ff_start_frame(inlink->dst->outputs[0], outpicref); } static av_cold void uninit(AVFilterContext *ctx) diff --git a/libavfilter/vf_settb.c b/libavfilter/vf_settb.c index 49092588e1..0a5ce4d173 100644 --- a/libavfilter/vf_settb.c +++ b/libavfilter/vf_settb.c @@ -104,7 +104,7 @@ static int config_output_props(AVFilterLink *outlink) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; @@ -118,7 +118,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) } inlink->cur_buf = NULL; - ff_start_frame(outlink, picref); + return ff_start_frame(outlink, picref); } AVFilter avfilter_vf_settb = { diff --git a/libavfilter/vf_slicify.c b/libavfilter/vf_slicify.c index 4b78dca493..09994875ca 100644 --- a/libavfilter/vf_slicify.c +++ b/libavfilter/vf_slicify.c @@ -59,7 +59,7 @@ static int config_props(AVFilterLink *link) return 0; } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { SliceContext *slice = link->dst->priv; @@ -75,7 +75,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) av_log(link->dst, AV_LOG_DEBUG, "h:%d\n", slice->h); link->cur_buf = NULL; - ff_start_frame(link->dst->outputs[0], picref); + return ff_start_frame(link->dst->outputs[0], picref); } static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index b236cc20aa..cafd17d42a 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -117,12 +117,15 @@ static int config_props_output(AVFilterLink *outlink) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterLink *outlink = inlink->dst->outputs[0]; outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + if (!outlink->out_buf) + return AVERROR(ENOMEM); + outlink->out_buf->pts = picref->pts; if (picref->video->pixel_aspect.num == 0) { @@ -132,7 +135,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) outlink->out_buf->video->pixel_aspect.den = picref->video->pixel_aspect.num; } - ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); + return ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); } static void end_frame(AVFilterLink *inlink) diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c index ec699705ab..c9a6c05be8 100644 --- a/libavfilter/vf_vflip.c +++ b/libavfilter/vf_vflip.c @@ -64,7 +64,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, return picref; } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) { FlipContext *flip = link->dst->priv; AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); @@ -79,7 +79,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) } } - ff_start_frame(link->dst->outputs[0], outpicref); + return ff_start_frame(link->dst->outputs[0], outpicref); } static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 02feeb213c..83bb4de222 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -201,7 +201,7 @@ static void return_frame(AVFilterContext *ctx, int is_second) yadif->frame_pending = (yadif->mode&1) && !is_second; } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { AVFilterContext *ctx = link->dst; YADIFContext *yadif = ctx->priv; @@ -216,7 +216,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) yadif->next = picref; if (!yadif->cur) - return; + return 0; if (yadif->auto_enable && !yadif->cur->video->interlaced) { yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); @@ -224,8 +224,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) yadif->prev = NULL; if (yadif->out->pts != AV_NOPTS_VALUE) yadif->out->pts *= 2; - ff_start_frame(ctx->outputs[0], yadif->out); - return; + return ff_start_frame(ctx->outputs[0], yadif->out); } if (!yadif->prev) @@ -238,7 +237,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) yadif->out->video->interlaced = 0; if (yadif->out->pts != AV_NOPTS_VALUE) yadif->out->pts *= 2; - ff_start_frame(ctx->outputs[0], yadif->out); + return ff_start_frame(ctx->outputs[0], yadif->out); } static void end_frame(AVFilterLink *link) diff --git a/libavfilter/video.c b/libavfilter/video.c index f61eafe19e..bdd79b5214 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -160,13 +160,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; @@ -175,18 +177,29 @@ static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) if (outlink) { 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); - ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); + return ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); } + 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; FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1); @@ -203,13 +216,22 @@ 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); } else link->cur_buf = picref; - start_frame(link, link->cur_buf); + ret = start_frame(link, link->cur_buf); + if (ret < 0) + clear_link(link); + + return ret; } void ff_null_end_frame(AVFilterLink *link) @@ -238,14 +260,7 @@ void ff_end_frame(AVFilterLink *link) 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; - } - avfilter_unref_bufferp(&link->cur_buf); - avfilter_unref_bufferp(&link->out_buf); + clear_link(link); } void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) diff --git a/libavfilter/video.h b/libavfilter/video.h index ce4e9c2992..3edf47addc 100644 --- a/libavfilter/video.h +++ b/libavfilter/video.h @@ -39,7 +39,7 @@ AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int h); -void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); +int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); void ff_null_end_frame(AVFilterLink *link); @@ -51,8 +51,11 @@ void ff_null_end_frame(AVFilterLink *link); * frame need only be valid once draw_slice() is called for that * portion. The receiving filter will free this reference when * it no longer needs it. + * + * @return >= 0 on success, a negative AVERROR on error. This function will + * unreference picref in case of error. */ -void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); +int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); /** * Notify the next filter that the current frame has finished. diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c index e64f85b9a7..8d656e111f 100644 --- a/libavfilter/vsink_nullsink.c +++ b/libavfilter/vsink_nullsink.c @@ -19,8 +19,9 @@ #include "avfilter.h" #include "internal.h" -static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { + return 0; } static void end_frame(AVFilterLink *link) From e9b992d035b58209d66115bd7d964741dd31d592 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 14 Jul 2012 09:25:33 +0200 Subject: [PATCH 02/16] lavfi: add error handling to draw_slice(). --- libavfilter/avfilter.h | 4 +++- libavfilter/fifo.c | 5 ++++- libavfilter/internal.h | 4 +++- libavfilter/split.c | 12 ++++++++---- libavfilter/vf_blackframe.c | 4 ++-- libavfilter/vf_boxblur.c | 4 ++-- libavfilter/vf_crop.c | 6 +++--- libavfilter/vf_delogo.c | 5 ++++- libavfilter/vf_drawbox.c | 4 ++-- libavfilter/vf_drawtext.c | 5 ++++- libavfilter/vf_fade.c | 4 ++-- libavfilter/vf_fieldorder.c | 5 +++-- libavfilter/vf_fps.c | 3 ++- libavfilter/vf_frei0r.c | 5 ++++- libavfilter/vf_gradfun.c | 5 ++++- libavfilter/vf_hflip.c | 4 ++-- libavfilter/vf_hqdn3d.c | 5 ++++- libavfilter/vf_libopencv.c | 5 ++++- libavfilter/vf_lut.c | 4 ++-- libavfilter/vf_overlay.c | 9 ++++++--- libavfilter/vf_pad.c | 18 +++++++++++------- libavfilter/vf_pixdesctest.c | 4 ++-- libavfilter/vf_scale.c | 10 +++++----- libavfilter/vf_select.c | 5 +++-- libavfilter/vf_slicify.c | 23 +++++++++++++++-------- libavfilter/vf_unsharp.c | 3 ++- libavfilter/vf_vflip.c | 4 ++-- libavfilter/vf_yadif.c | 5 ++++- libavfilter/video.c | 20 ++++++++++++-------- libavfilter/video.h | 6 ++++-- 30 files changed, 128 insertions(+), 72 deletions(-) diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index a685761cfb..3cd65da1e7 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -295,8 +295,10 @@ struct AVFilterPad { * and should do its processing. * * Input video pads only. + * + * @return >= 0 on success, a negative AVERROR on error. */ - void (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); + int (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); /** * Samples filtering callback. This is where a filter receives audio data diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index 185960ebc7..f7788b26a6 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -100,7 +100,10 @@ static void queue_pop(FifoContext *s) static void end_frame(AVFilterLink *inlink) { } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +{ + return 0; +} /** * Move data pointers and pts offset samples forward. diff --git a/libavfilter/internal.h b/libavfilter/internal.h index c08e00bcb8..3a2d50d65c 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -106,8 +106,10 @@ struct AVFilterPad { * and should do its processing. * * Input video pads only. + * + * @return >= 0 on success, a negative AVERROR on error. */ - void (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); + int (*draw_slice)(AVFilterLink *link, int y, int height, int slice_dir); /** * Samples filtering callback. This is where a filter receives audio data diff --git a/libavfilter/split.c b/libavfilter/split.c index 5ffbc856f6..0ae0a60056 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -77,13 +77,17 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) return ret; } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterContext *ctx = inlink->dst; - int i; + int i, ret = 0; - for (i = 0; i < ctx->nb_outputs; i++) - ff_draw_slice(ctx->outputs[i], y, h, slice_dir); + for (i = 0; i < ctx->nb_outputs; i++) { + ret = ff_draw_slice(ctx->outputs[i], y, h, slice_dir); + if (ret < 0) + break; + } + return ret; } static void end_frame(AVFilterLink *inlink) diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index f5301c66c5..9fd544921b 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -74,7 +74,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args) return 0; } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterContext *ctx = inlink->dst; BlackFrameContext *blackframe = ctx->priv; @@ -88,7 +88,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) p += picref->linesize[0]; } - ff_draw_slice(ctx->outputs[0], y, h, slice_dir); + return ff_draw_slice(ctx->outputs[0], y, h, slice_dir); } static void end_frame(AVFilterLink *inlink) diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c index 9ecd78f87c..0247e93e6b 100644 --- a/libavfilter/vf_boxblur.c +++ b/libavfilter/vf_boxblur.c @@ -306,7 +306,7 @@ static void vblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_li h, radius, power, temp); } -static void draw_slice(AVFilterLink *inlink, int y0, int h0, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y0, int h0, int slice_dir) { AVFilterContext *ctx = inlink->dst; BoxBlurContext *boxblur = ctx->priv; @@ -330,7 +330,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h0, int slice_dir) w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane], boxblur->temp); - ff_draw_slice(outlink, y0, h0, slice_dir); + return ff_draw_slice(outlink, y0, h0, slice_dir); } AVFilter avfilter_vf_boxblur = { diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index 636e853259..f7d311a9a8 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -297,13 +297,13 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) return ff_start_frame(link->dst->outputs[0], ref2); } -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { AVFilterContext *ctx = link->dst; CropContext *crop = ctx->priv; if (y >= crop->y + crop->h || y + h <= crop->y) - return; + return 0; if (y < crop->y) { h -= crop->y - y; @@ -312,7 +312,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) if (y + h > crop->y + crop->h) h = crop->y + crop->h - y; - ff_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir); + return ff_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir); } static void end_frame(AVFilterLink *link) diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index 5f8f9ff6ff..6e77cf19a8 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -245,7 +245,10 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) return 0; } -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } +static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +{ + return 0; +} static void end_frame(AVFilterLink *inlink) { diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c index 3c35bb5e8d..96b1c00911 100644 --- a/libavfilter/vf_drawbox.c +++ b/libavfilter/vf_drawbox.c @@ -94,7 +94,7 @@ static int config_input(AVFilterLink *inlink) return 0; } -static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir) { DrawBoxContext *drawbox = inlink->dst->priv; int plane, x, y, xb = drawbox->x, yb = drawbox->y; @@ -120,7 +120,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir) } } - ff_draw_slice(inlink->dst->outputs[0], y0, h, 1); + return ff_draw_slice(inlink->dst->outputs[0], y0, h, 1); } AVFilter avfilter_vf_drawbox = { diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index f9a92615c9..732ab32aaa 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -791,7 +791,10 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref, return 0; } -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } +static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +{ + return 0; +} static inline int normalize_double(int *n, double d) { diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index f67e4a81bd..0a2a655cce 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -97,7 +97,7 @@ static int config_props(AVFilterLink *inlink) return 0; } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { FadeContext *fade = inlink->dst->priv; AVFilterBufferRef *outpic = inlink->cur_buf; @@ -134,7 +134,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } } - ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); } static void end_frame(AVFilterLink *inlink) diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c index 0a8af75851..312ff4fc26 100644 --- a/libavfilter/vf_fieldorder.c +++ b/libavfilter/vf_fieldorder.c @@ -144,7 +144,7 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) return 0; } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterContext *ctx = inlink->dst; FieldOrderContext *fieldorder = ctx->priv; @@ -158,8 +158,9 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) * and that complexity will be added later */ if ( !inpicref->video->interlaced || inpicref->video->top_field_first == fieldorder->dst_tff) { - ff_draw_slice(outlink, y, h, slice_dir); + return ff_draw_slice(outlink, y, h, slice_dir); } + return 0; } static void end_frame(AVFilterLink *inlink) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index ca0d36630d..619a86cc11 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -248,8 +248,9 @@ static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf) return 0; } -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { + return 0; } AVFilter avfilter_vf_fps = { diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 0b149d39ad..21221e1ed8 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -340,7 +340,10 @@ static int query_formats(AVFilterContext *ctx) return 0; } -static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } +static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +{ + return 0; +} static void end_frame(AVFilterLink *inlink) { diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 83186e561e..61be40c913 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -210,7 +210,10 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) return 0; } -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } +static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +{ + return 0; +} static void end_frame(AVFilterLink *inlink) { diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c index fc549aa104..06c42483d1 100644 --- a/libavfilter/vf_hflip.c +++ b/libavfilter/vf_hflip.c @@ -81,7 +81,7 @@ static int config_props(AVFilterLink *inlink) return 0; } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { FlipContext *flip = inlink->dst->priv; AVFilterBufferRef *inpic = inlink->cur_buf; @@ -142,7 +142,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } } - ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); } AVFilter avfilter_vf_hflip = { diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index 75594db0ab..3985ce4501 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -290,7 +290,10 @@ static int config_input(AVFilterLink *inlink) return 0; } -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } +static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +{ + return 0; +} static void end_frame(AVFilterLink *inlink) { diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index 176065d506..aa30d36880 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -67,7 +67,10 @@ static int query_formats(AVFilterContext *ctx) return 0; } -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } +static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +{ + return 0; +} typedef struct { const char *name; diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index cdc9375f93..c56c55b88c 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -294,7 +294,7 @@ static int config_props(AVFilterLink *inlink) return 0; } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterContext *ctx = inlink->dst; LutContext *lut = ctx->priv; @@ -339,7 +339,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } } - ff_draw_slice(outlink, y, h, slice_dir); + return ff_draw_slice(outlink, y, h, slice_dir); } static const AVFilterPad inputs[] = { diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 926e9a205c..2b9439c911 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -320,7 +320,7 @@ static void blend_slice(AVFilterContext *ctx, } } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; @@ -334,7 +334,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) over->overpicref->video->w, over->overpicref->video->h, y, outpicref->video->w, h); } - ff_draw_slice(outlink, y, h, slice_dir); + return ff_draw_slice(outlink, y, h, slice_dir); } static void end_frame(AVFilterLink *inlink) @@ -342,7 +342,10 @@ static void end_frame(AVFilterLink *inlink) ff_end_frame(inlink->dst->outputs[0]); } -static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { } +static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +{ + return 0; +} static void null_end_frame(AVFilterLink *inlink) { } diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 298aae4131..2f641f2eb6 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -367,10 +367,10 @@ static void end_frame(AVFilterLink *link) ff_end_frame(link->dst->outputs[0]); } -static void draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice) +static int draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice) { PadContext *pad = link->dst->priv; - int bar_y, bar_h = 0; + int bar_y, bar_h = 0, ret = 0; if (slice_dir * before_slice == 1 && y == pad->y) { /* top bar */ @@ -387,15 +387,17 @@ static void draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, link->dst->outputs[0]->out_buf->linesize, pad->line, pad->line_step, pad->hsub, pad->vsub, 0, bar_y, pad->w, bar_h); - ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir); + ret = ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir); } + return ret; } -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { PadContext *pad = link->dst->priv; AVFilterBufferRef *outpic = link->dst->outputs[0]->out_buf; AVFilterBufferRef *inpic = link->cur_buf; + int ret; y += pad->y; @@ -403,7 +405,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) h &= ~((1 << pad->vsub) - 1); if (!h) - return; + return 0; draw_send_bar_slice(link, y, h, slice_dir, 1); /* left border */ @@ -421,9 +423,11 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) ff_draw_rectangle(outpic->data, outpic->linesize, pad->line, pad->line_step, pad->hsub, pad->vsub, pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h); - ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); + ret = ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); + if (ret < 0) + return ret; - draw_send_bar_slice(link, y, h, slice_dir, -1); + return draw_send_bar_slice(link, y, h, slice_dir, -1); } AVFilter avfilter_vf_pad = { diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c index ae0a5063d2..caf0852045 100644 --- a/libavfilter/vf_pixdesctest.c +++ b/libavfilter/vf_pixdesctest.c @@ -90,7 +90,7 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) return 0; } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { PixdescTestContext *priv = inlink->dst->priv; AVFilterBufferRef *inpic = inlink->cur_buf; @@ -117,7 +117,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } } - ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); } AVFilter avfilter_vf_pixdesctest = { diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 6c5421006b..73f31a65fd 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -291,16 +291,15 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) return 0; } -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { ScaleContext *scale = link->dst->priv; - int out_h; + int out_h, ret; AVFilterBufferRef *cur_pic = link->cur_buf; const uint8_t *data[4]; if (!scale->sws) { - ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); - return; + return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); } if (scale->slice_y == 0 && slice_dir == -1) @@ -319,9 +318,10 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) if (slice_dir == -1) scale->slice_y -= out_h; - ff_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir); + ret = ff_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir); if (slice_dir == 1) scale->slice_y += out_h; + return ret; } AVFilter avfilter_vf_scale = { diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index 8b3a6f84a5..a4bb2dfe2b 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -249,12 +249,13 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) return 0; } -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { SelectContext *select = inlink->dst->priv; if (select->select && !select->cache_frames) - ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + return 0; } static void end_frame(AVFilterLink *inlink) diff --git a/libavfilter/vf_slicify.c b/libavfilter/vf_slicify.c index 09994875ca..3c69cfd350 100644 --- a/libavfilter/vf_slicify.c +++ b/libavfilter/vf_slicify.c @@ -78,24 +78,31 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) return ff_start_frame(link->dst->outputs[0], picref); } -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { SliceContext *slice = link->dst->priv; - int y2; + int y2, ret = 0; if (slice_dir == 1) { - for (y2 = y; y2 + slice->h <= y + h; y2 += slice->h) - ff_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir); + for (y2 = y; y2 + slice->h <= y + h; y2 += slice->h) { + ret = ff_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir); + if (ret < 0) + return ret; + } if (y2 < y + h) - ff_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir); + return ff_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir); } else if (slice_dir == -1) { - for (y2 = y + h; y2 - slice->h >= y; y2 -= slice->h) - ff_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir); + for (y2 = y + h; y2 - slice->h >= y; y2 -= slice->h) { + ret = ff_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir); + if (ret < 0) + return ret; + } if (y2 > y) - ff_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir); + return ff_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir); } + return 0; } AVFilter avfilter_vf_slicify = { diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index dcf4ebeeb0..41bcae2dd1 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -229,8 +229,9 @@ static void end_frame(AVFilterLink *link) ff_end_frame(link->dst->outputs[0]); } -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { + return 0; } AVFilter avfilter_vf_unsharp = { diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c index c9a6c05be8..dc7604c52a 100644 --- a/libavfilter/vf_vflip.c +++ b/libavfilter/vf_vflip.c @@ -82,11 +82,11 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) return ff_start_frame(link->dst->outputs[0], outpicref); } -static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { AVFilterContext *ctx = link->dst; - ff_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir); + return ff_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir); } AVFilter avfilter_vf_vflip = { diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 83bb4de222..19652aa465 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -377,7 +377,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args) return 0; } -static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } +static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +{ + return 0; +} static int config_props(AVFilterLink *link) { diff --git a/libavfilter/video.c b/libavfilter/video.c index bdd79b5214..ffcc2347fc 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -263,12 +263,12 @@ void ff_end_frame(AVFilterLink *link) clear_link(link); } -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 +276,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_DPRINTF_START(NULL, draw_slice); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir); @@ -317,5 +318,8 @@ 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; } diff --git a/libavfilter/video.h b/libavfilter/video.h index 3edf47addc..893960e7c1 100644 --- a/libavfilter/video.h +++ b/libavfilter/video.h @@ -40,7 +40,7 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int h); int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); -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); void ff_null_end_frame(AVFilterLink *link); /** @@ -78,7 +78,9 @@ void ff_end_frame(AVFilterLink *link); * from the top slice to the bottom slice if the value is 1, * from the bottom slice to the top slice if the value is -1, * for other values the behavior of the function is undefined. + * + * @return >= 0 on success, a negative AVERROR on error. */ -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); #endif /* AVFILTER_VIDEO_H */ From d4f89906e3b310609b636cf6071313ec557ec873 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 14 Jul 2012 09:25:33 +0200 Subject: [PATCH 03/16] lavfi: add error handling to end_frame(). --- libavfilter/avfilter.h | 4 +++- libavfilter/fifo.c | 5 ++++- libavfilter/internal.h | 4 +++- libavfilter/split.c | 12 ++++++++---- libavfilter/vf_blackframe.c | 4 ++-- libavfilter/vf_crop.c | 4 ++-- libavfilter/vf_cropdetect.c | 4 ++-- libavfilter/vf_delogo.c | 9 ++++++--- libavfilter/vf_drawtext.c | 9 ++++++--- libavfilter/vf_fade.c | 7 +++++-- libavfilter/vf_fieldorder.c | 4 ++-- libavfilter/vf_fps.c | 17 +++++++++-------- libavfilter/vf_frei0r.c | 9 ++++++--- libavfilter/vf_gradfun.c | 10 ++++++---- libavfilter/vf_hqdn3d.c | 9 ++++++--- libavfilter/vf_libopencv.c | 9 ++++++--- libavfilter/vf_overlay.c | 9 ++++++--- libavfilter/vf_pad.c | 4 ++-- libavfilter/vf_select.c | 7 ++++--- libavfilter/vf_showinfo.c | 4 ++-- libavfilter/vf_transpose.c | 10 ++++++---- libavfilter/vf_unsharp.c | 9 ++++++--- libavfilter/vf_yadif.c | 12 +++++++----- libavfilter/video.c | 18 +++++++++++------- libavfilter/video.h | 6 ++++-- libavfilter/vsink_nullsink.c | 3 ++- 26 files changed, 126 insertions(+), 76 deletions(-) diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 3cd65da1e7..7ca9eb42b3 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -287,8 +287,10 @@ struct AVFilterPad { * in the link structure during start_frame(). * * Input video pads only. + * + * @return >= 0 on success, a negative AVERROR on error. */ - void (*end_frame)(AVFilterLink *link); + int (*end_frame)(AVFilterLink *link); /** * Slice drawing callback. This is where a filter receives video data diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index f7788b26a6..16a86b3565 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -98,7 +98,10 @@ static void queue_pop(FifoContext *s) s->root.next = tmp; } -static void end_frame(AVFilterLink *inlink) { } +static int end_frame(AVFilterLink *inlink) +{ + return 0; +} static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 3a2d50d65c..6f868ae89f 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -98,8 +98,10 @@ struct AVFilterPad { * in the link structure during start_frame(). * * Input video pads only. + * + * @return >= 0 on success, a negative AVERROR on error. */ - void (*end_frame)(AVFilterLink *link); + int (*end_frame)(AVFilterLink *link); /** * Slice drawing callback. This is where a filter receives video data diff --git a/libavfilter/split.c b/libavfilter/split.c index 0ae0a60056..469f69d76a 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -90,13 +90,17 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) return ret; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; - int i; + int i, ret = 0; - for (i = 0; i < ctx->nb_outputs; i++) - ff_end_frame(ctx->outputs[i]); + for (i = 0; i < ctx->nb_outputs; i++) { + ret = ff_end_frame(ctx->outputs[i]); + if (ret < 0) + break; + } + return ret; } AVFilter avfilter_vf_split = { diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index 9fd544921b..bf0b18bea3 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -91,7 +91,7 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) return ff_draw_slice(ctx->outputs[0], y, h, slice_dir); } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; BlackFrameContext *blackframe = ctx->priv; @@ -106,7 +106,7 @@ static void end_frame(AVFilterLink *inlink) blackframe->frame++; blackframe->nblack = 0; - ff_end_frame(inlink->dst->outputs[0]); + return ff_end_frame(inlink->dst->outputs[0]); } AVFilter avfilter_vf_blackframe = { diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index f7d311a9a8..4361ba5a8c 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -315,12 +315,12 @@ static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) return ff_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir); } -static void end_frame(AVFilterLink *link) +static int end_frame(AVFilterLink *link) { CropContext *crop = link->dst->priv; crop->var_values[VAR_N] += 1.0; - ff_end_frame(link->dst->outputs[0]); + return ff_end_frame(link->dst->outputs[0]); } AVFilter avfilter_vf_crop = { diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c index 1790f4b4e5..8b6063c996 100644 --- a/libavfilter/vf_cropdetect.c +++ b/libavfilter/vf_cropdetect.c @@ -114,7 +114,7 @@ static int config_input(AVFilterLink *inlink) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; CropDetectContext *cd = ctx->priv; @@ -191,7 +191,7 @@ static void end_frame(AVFilterLink *inlink) w, h, x, y); } - ff_end_frame(inlink->dst->outputs[0]); + return ff_end_frame(inlink->dst->outputs[0]); } AVFilter avfilter_vf_cropdetect = { diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index 6e77cf19a8..81f33b727e 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -250,7 +250,7 @@ static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { DelogoContext *delogo = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; @@ -260,6 +260,7 @@ static void end_frame(AVFilterLink *inlink) int hsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_w; int vsub0 = av_pix_fmt_descriptors[inlink->format].log2_chroma_h; int plane; + int ret; for (plane = 0; plane < 4 && inpicref->data[plane]; plane++) { int hsub = plane == 1 || plane == 2 ? hsub0 : 0; @@ -274,8 +275,10 @@ static void end_frame(AVFilterLink *inlink) delogo->show, direct); } - ff_draw_slice(outlink, 0, inlink->h, 1); - ff_end_frame(outlink); + if ((ret = ff_draw_slice(outlink, 0, inlink->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; + return 0; } AVFilter avfilter_vf_delogo = { diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 732ab32aaa..30bdcea16d 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -860,19 +860,22 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) return ff_start_frame(inlink->dst->outputs[0], buf_out); } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *picref = inlink->cur_buf; DrawTextContext *dtext = inlink->dst->priv; + int ret; if (dtext->draw) draw_text(inlink->dst, picref, picref->video->w, picref->video->h); dtext->var_values[VAR_N] += 1.0; - ff_draw_slice(outlink, 0, picref->video->h, 1); - ff_end_frame(outlink); + if ((ret = ff_draw_slice(outlink, 0, picref->video->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; + return 0; } AVFilter avfilter_vf_drawtext = { diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 0a2a655cce..c30a862ad6 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -137,17 +137,20 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { FadeContext *fade = inlink->dst->priv; + int ret; - ff_end_frame(inlink->dst->outputs[0]); + ret = ff_end_frame(inlink->dst->outputs[0]); if (fade->frame_index >= fade->start_frame && fade->frame_index <= fade->stop_frame) fade->factor += fade->fade_per_frame; fade->factor = av_clip_uint16(fade->factor); fade->frame_index++; + + return ret; } AVFilter avfilter_vf_fade = { diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c index 312ff4fc26..4ea7fe1127 100644 --- a/libavfilter/vf_fieldorder.c +++ b/libavfilter/vf_fieldorder.c @@ -163,7 +163,7 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; FieldOrderContext *fieldorder = ctx->priv; @@ -227,7 +227,7 @@ static void end_frame(AVFilterLink *inlink) "not interlaced or field order already correct\n"); } - ff_end_frame(outlink); + return ff_end_frame(outlink); } AVFilter avfilter_vf_fieldorder = { diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index 619a86cc11..9ca0668c76 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -166,14 +166,14 @@ static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; FPSContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; AVFilterBufferRef *buf = inlink->cur_buf; int64_t delta; - int i; + int i, ret; inlink->cur_buf = NULL; s->frames_in++; @@ -188,13 +188,12 @@ static void end_frame(AVFilterLink *inlink) avfilter_unref_buffer(buf); s->drop++; } - return; + return 0; } /* now wait for the next timestamp */ if (buf->pts == AV_NOPTS_VALUE) { - write_to_fifo(s->fifo, buf); - return; + return write_to_fifo(s->fifo, buf); } /* number of output frames */ @@ -211,10 +210,10 @@ static void end_frame(AVFilterLink *inlink) av_fifo_generic_read(s->fifo, &tmp, sizeof(tmp), NULL); flush_fifo(s->fifo); - write_to_fifo(s->fifo, tmp); + ret = write_to_fifo(s->fifo, tmp); avfilter_unref_buffer(buf); - return; + return ret; } /* can output >= 1 frames */ @@ -239,8 +238,10 @@ static void end_frame(AVFilterLink *inlink) } flush_fifo(s->fifo); - write_to_fifo(s->fifo, buf); + ret = write_to_fifo(s->fifo, buf); s->pts = s->first_pts + av_rescale_q(s->frames_out, outlink->time_base, inlink->time_base); + + return ret; } static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *buf) diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 21221e1ed8..4721779348 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -345,18 +345,21 @@ static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { Frei0rContext *frei0r = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *inpicref = inlink->cur_buf; AVFilterBufferRef *outpicref = outlink->out_buf; + int ret; frei0r->update(frei0r->instance, inpicref->pts * av_q2d(inlink->time_base) * 1000, (const uint32_t *)inpicref->data[0], (uint32_t *)outpicref->data[0]); - ff_draw_slice(outlink, 0, outlink->h, 1); - ff_end_frame(outlink); + if ((ret = ff_draw_slice(outlink, 0, outlink->h, 1)) || + (ret = ff_end_frame(outlink)) < 0) + return ret; + return 0; } AVFilter avfilter_vf_frei0r = { diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 61be40c913..d73e833865 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -215,13 +215,13 @@ static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { GradFunContext *gf = inlink->dst->priv; AVFilterBufferRef *inpic = inlink->cur_buf; AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *outpic = outlink->out_buf; - int p; + int p, ret; for (p = 0; p < 4 && inpic->data[p]; p++) { int w = inlink->w; @@ -239,8 +239,10 @@ static void end_frame(AVFilterLink *inlink) av_image_copy_plane(outpic->data[p], outpic->linesize[p], inpic->data[p], inpic->linesize[p], w, h); } - ff_draw_slice(outlink, 0, inlink->h, 1); - ff_end_frame(outlink); + if ((ret = ff_draw_slice(outlink, 0, inlink->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; + return 0; } AVFilter avfilter_vf_gradfun = { diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index 3985ce4501..9e01606041 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -295,7 +295,7 @@ static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { HQDN3DContext *hqdn3d = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; @@ -303,6 +303,7 @@ static void end_frame(AVFilterLink *inlink) AVFilterBufferRef *outpic = outlink->out_buf; int cw = inpic->video->w >> hqdn3d->hsub; int ch = inpic->video->h >> hqdn3d->vsub; + int ret; deNoise(inpic->data[0], outpic->data[0], hqdn3d->Line, &hqdn3d->Frame[0], inpic->video->w, inpic->video->h, @@ -323,8 +324,10 @@ static void end_frame(AVFilterLink *inlink) hqdn3d->Coefs[2], hqdn3d->Coefs[3]); - ff_draw_slice(outlink, 0, inpic->video->h, 1); - ff_end_frame(outlink); + if ((ret = ff_draw_slice(outlink, 0, inpic->video->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; + return 0; } AVFilter avfilter_vf_hqdn3d = { diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index aa30d36880..e60caf2bc3 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -354,7 +354,7 @@ static av_cold void uninit(AVFilterContext *ctx) memset(ocv, 0, sizeof(*ocv)); } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; OCVContext *ocv = ctx->priv; @@ -362,14 +362,17 @@ static void end_frame(AVFilterLink *inlink) AVFilterBufferRef *inpicref = inlink ->cur_buf; AVFilterBufferRef *outpicref = outlink->out_buf; IplImage inimg, outimg; + int ret; fill_iplimage_from_picref(&inimg , inpicref , inlink->format); fill_iplimage_from_picref(&outimg, outpicref, inlink->format); ocv->end_frame_filter(ctx, &inimg, &outimg); fill_picref_from_iplimage(outpicref, &outimg, inlink->format); - ff_draw_slice(outlink, 0, outlink->h, 1); - ff_end_frame(outlink); + if ((ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; + return 0; } AVFilter avfilter_vf_ocv = { diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 2b9439c911..a0c423de26 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -337,9 +337,9 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) return ff_draw_slice(outlink, y, h, slice_dir); } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { - ff_end_frame(inlink->dst->outputs[0]); + return ff_end_frame(inlink->dst->outputs[0]); } static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) @@ -347,7 +347,10 @@ static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) return 0; } -static void null_end_frame(AVFilterLink *inlink) { } +static int null_end_frame(AVFilterLink *inlink) +{ + return 0; +} static int poll_frame(AVFilterLink *link) { diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 2f641f2eb6..262a416488 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -362,9 +362,9 @@ fail: return ret; } -static void end_frame(AVFilterLink *link) +static int end_frame(AVFilterLink *link) { - ff_end_frame(link->dst->outputs[0]); + return ff_end_frame(link->dst->outputs[0]); } static int draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice) diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index a4bb2dfe2b..b9e053fc03 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -258,15 +258,16 @@ static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { SelectContext *select = inlink->dst->priv; if (select->select) { if (select->cache_frames) - return; - ff_end_frame(inlink->dst->outputs[0]); + return 0; + return ff_end_frame(inlink->dst->outputs[0]); } + return 0; } static int request_frame(AVFilterLink *outlink) diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index cc1360e76c..254141d677 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -40,7 +40,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; ShowInfoContext *showinfo = ctx->priv; @@ -76,7 +76,7 @@ static void end_frame(AVFilterLink *inlink) checksum, plane_checksum[0], plane_checksum[1], plane_checksum[2], plane_checksum[3]); showinfo->frame++; - ff_end_frame(inlink->dst->outputs[0]); + return ff_end_frame(inlink->dst->outputs[0]); } AVFilter avfilter_vf_showinfo = { diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index cafd17d42a..49b54d760b 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -138,13 +138,13 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) return ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { TransContext *trans = inlink->dst->priv; AVFilterBufferRef *inpic = inlink->cur_buf; AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf; AVFilterLink *outlink = inlink->dst->outputs[0]; - int plane; + int plane, ret; for (plane = 0; outpic->data[plane]; plane++) { int hsub = plane == 1 || plane == 2 ? trans->hsub : 0; @@ -195,8 +195,10 @@ static void end_frame(AVFilterLink *inlink) } } - ff_draw_slice(outlink, 0, outpic->video->h, 1); - ff_end_frame(outlink); + if ((ret = ff_draw_slice(outlink, 0, outpic->video->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; + return 0; } AVFilter avfilter_vf_transpose = { diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 41bcae2dd1..6140c75a87 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -213,20 +213,23 @@ static av_cold void uninit(AVFilterContext *ctx) free_filter_param(&unsharp->chroma); } -static void end_frame(AVFilterLink *link) +static int end_frame(AVFilterLink *link) { UnsharpContext *unsharp = link->dst->priv; AVFilterBufferRef *in = link->cur_buf; AVFilterBufferRef *out = link->dst->outputs[0]->out_buf; int cw = SHIFTUP(link->w, unsharp->hsub); int ch = SHIFTUP(link->h, unsharp->vsub); + int ret; apply_unsharp(out->data[0], out->linesize[0], in->data[0], in->linesize[0], link->w, link->h, &unsharp->luma); apply_unsharp(out->data[1], out->linesize[1], in->data[1], in->linesize[1], cw, ch, &unsharp->chroma); apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw, ch, &unsharp->chroma); - ff_draw_slice(link->dst->outputs[0], 0, link->h, 1); - ff_end_frame(link->dst->outputs[0]); + if ((ret = ff_draw_slice(link->dst->outputs[0], 0, link->h, 1)) < 0 || + (ret = ff_end_frame(link->dst->outputs[0])) < 0) + return ret; + return 0; } static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir) diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 19652aa465..69efc8a08a 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -240,21 +240,23 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) return ff_start_frame(ctx->outputs[0], yadif->out); } -static void end_frame(AVFilterLink *link) +static int end_frame(AVFilterLink *link) { AVFilterContext *ctx = link->dst; YADIFContext *yadif = ctx->priv; if (!yadif->out) - return; + return 0; if (yadif->auto_enable && !yadif->cur->video->interlaced) { - ff_draw_slice(ctx->outputs[0], 0, link->h, 1); - ff_end_frame(ctx->outputs[0]); - return; + int ret = ff_draw_slice(ctx->outputs[0], 0, link->h, 1); + if (ret >= 0) + ret = ff_end_frame(ctx->outputs[0]); + return ret; } return_frame(ctx, 0); + return 0; } static int request_frame(AVFilterLink *link) diff --git a/libavfilter/video.c b/libavfilter/video.c index ffcc2347fc..8dd5bf4272 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -234,12 +234,12 @@ int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) return ret; } -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; @@ -247,20 +247,24 @@ 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); clear_link(link); + + return ret; } int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) diff --git a/libavfilter/video.h b/libavfilter/video.h index 893960e7c1..ef4a1a9c32 100644 --- a/libavfilter/video.h +++ b/libavfilter/video.h @@ -41,7 +41,7 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); -void ff_null_end_frame(AVFilterLink *link); +int ff_null_end_frame(AVFilterLink *link); /** * Notify the next filter of the start of a frame. @@ -61,8 +61,10 @@ int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); * Notify the next filter that the current frame has finished. * * @param link the output link the frame was sent over + * + * @return >= 0 on success, a negative AVERROR on error */ -void ff_end_frame(AVFilterLink *link); +int ff_end_frame(AVFilterLink *link); /** * Send a slice to the next filter. diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c index 8d656e111f..e03dcf0085 100644 --- a/libavfilter/vsink_nullsink.c +++ b/libavfilter/vsink_nullsink.c @@ -24,8 +24,9 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) return 0; } -static void end_frame(AVFilterLink *link) +static int end_frame(AVFilterLink *link) { + return 0; } AVFilter avfilter_vsink_nullsink = { From 3825b5268844694ff50a0e0bfde64df43a862fae Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 09:47:01 +0200 Subject: [PATCH 04/16] lavfi: check all ff_start_frame/draw_slice/end_frame calls for errors --- libavfilter/buffersrc.c | 8 +++++--- libavfilter/fifo.c | 8 +++++--- libavfilter/vf_fps.c | 18 ++++++++++++------ libavfilter/vf_frei0r.c | 18 ++++++++++++++---- libavfilter/vf_select.c | 11 +++++++---- libavfilter/vf_yadif.c | 14 +++++++++----- libavfilter/vsrc_color.c | 18 ++++++++++++++---- libavfilter/vsrc_movie.c | 15 +++++++++++---- libavfilter/vsrc_testsrc.c | 8 +++++--- 9 files changed, 82 insertions(+), 36 deletions(-) diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index 0828b153d8..2aa7d7d118 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -323,9 +323,10 @@ static int request_frame(AVFilterLink *link) switch (link->type) { case AVMEDIA_TYPE_VIDEO: - ff_start_frame(link, avfilter_ref_buffer(buf, ~0)); - ff_draw_slice(link, 0, link->h, 1); - ff_end_frame(link); + if ((ret = ff_start_frame(link, avfilter_ref_buffer(buf, ~0))) < 0 || + (ret = ff_draw_slice(link, 0, link->h, 1)) < 0 || + (ret = ff_end_frame(link)) < 0) + goto fail; break; case AVMEDIA_TYPE_AUDIO: ret = ff_filter_samples(link, avfilter_ref_buffer(buf, ~0)); @@ -334,6 +335,7 @@ static int request_frame(AVFilterLink *link) return AVERROR(EINVAL); } +fail: avfilter_unref_buffer(buf); return ret; diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index 16a86b3565..66de62c3b0 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -241,9 +241,11 @@ static int request_frame(AVFilterLink *outlink) * so we don't have to worry about dereferencing it ourselves. */ switch (outlink->type) { case AVMEDIA_TYPE_VIDEO: - ff_start_frame(outlink, fifo->root.next->buf); - ff_draw_slice (outlink, 0, outlink->h, 1); - ff_end_frame (outlink); + if ((ret = ff_start_frame(outlink, fifo->root.next->buf)) < 0 || + (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; + queue_pop(fifo); break; case AVMEDIA_TYPE_AUDIO: diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index 9ca0668c76..ab7cba57d1 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -143,9 +143,11 @@ static int request_frame(AVFilterLink *outlink) buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, outlink->time_base) + s->frames_out; - ff_start_frame(outlink, buf); - ff_draw_slice(outlink, 0, outlink->h, 1); - ff_end_frame(outlink); + if ((ret = ff_start_frame(outlink, buf)) < 0 || + (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; + s->frames_out++; } return 0; @@ -231,9 +233,13 @@ static int end_frame(AVFilterLink *inlink) buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base, outlink->time_base) + s->frames_out; - ff_start_frame(outlink, buf_out); - ff_draw_slice(outlink, 0, outlink->h, 1); - ff_end_frame(outlink); + if ((ret = ff_start_frame(outlink, buf_out)) < 0 || + (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) { + avfilter_unref_bufferp(&buf); + return ret; + } + s->frames_out++; } flush_fifo(s->fifo); diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 4721779348..f5e9128d31 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -438,18 +438,28 @@ static int source_request_frame(AVFilterLink *outlink) { Frei0rContext *frei0r = outlink->src->priv; AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + int ret; + picref->video->pixel_aspect = (AVRational) {1, 1}; picref->pts = frei0r->pts++; picref->pos = -1; - ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); + ret = ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); + if (ret < 0) + goto fail; + frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}), NULL, (uint32_t *)picref->data[0]); - ff_draw_slice(outlink, 0, outlink->h, 1); - ff_end_frame(outlink); + ret = ff_draw_slice(outlink, 0, outlink->h, 1); + if (ret < 0) + goto fail; + + ret = ff_end_frame(outlink); + +fail: avfilter_unref_buffer(picref); - return 0; + return ret; } AVFilter avfilter_vsrc_frei0r_src = { diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index b9e053fc03..d4cfbe9ceb 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -279,12 +279,15 @@ static int request_frame(AVFilterLink *outlink) if (av_fifo_size(select->pending_frames)) { AVFilterBufferRef *picref; + int ret; + av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL); - ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); - ff_draw_slice(outlink, 0, outlink->h, 1); - ff_end_frame(outlink); + if ((ret = ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0))) < 0 || + (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0); + avfilter_unref_buffer(picref); - return 0; + return ret; } while (!select->select) { diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 69efc8a08a..9ac11bf959 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -157,11 +157,11 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, int w, return picref; } -static void return_frame(AVFilterContext *ctx, int is_second) +static int return_frame(AVFilterContext *ctx, int is_second) { YADIFContext *yadif = ctx->priv; AVFilterLink *link= ctx->outputs[0]; - int tff; + int tff, ret; if (yadif->parity == -1) { tff = yadif->cur->video->interlaced ? @@ -193,12 +193,16 @@ static void return_frame(AVFilterContext *ctx, int is_second) } else { yadif->out->pts = AV_NOPTS_VALUE; } - ff_start_frame(ctx->outputs[0], yadif->out); + ret = ff_start_frame(ctx->outputs[0], yadif->out); + if (ret < 0) + return ret; } - ff_draw_slice(ctx->outputs[0], 0, link->h, 1); - ff_end_frame(ctx->outputs[0]); + if ((ret = ff_draw_slice(ctx->outputs[0], 0, link->h, 1)) < 0 || + (ret = ff_end_frame(ctx->outputs[0])) < 0) + return ret; yadif->frame_pending = (yadif->mode&1) && !is_second; + return 0; } static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index d5bda2b698..c17f54f39d 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -142,19 +142,29 @@ static int color_request_frame(AVFilterLink *link) { ColorContext *color = link->src->priv; AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h); + int ret; + picref->video->pixel_aspect = (AVRational) {1, 1}; picref->pts = color->pts++; picref->pos = -1; - ff_start_frame(link, avfilter_ref_buffer(picref, ~0)); + ret = ff_start_frame(link, avfilter_ref_buffer(picref, ~0)); + if (ret < 0) + goto fail; + ff_draw_rectangle(picref->data, picref->linesize, color->line, color->line_step, color->hsub, color->vsub, 0, 0, color->w, color->h); - ff_draw_slice(link, 0, color->h, 1); - ff_end_frame(link); + ret = ff_draw_slice(link, 0, color->h, 1); + if (ret < 0) + goto fail; + + ret = ff_end_frame(link); + +fail: avfilter_unref_buffer(picref); - return 0; + return ret; } AVFilter avfilter_vsrc_color = { diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index 11769d0339..1fb0495e82 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -289,13 +289,20 @@ static int request_frame(AVFilterLink *outlink) return ret; outpicref = avfilter_ref_buffer(movie->picref, ~0); - ff_start_frame(outlink, outpicref); - ff_draw_slice(outlink, 0, outlink->h, 1); - ff_end_frame(outlink); + ret = ff_start_frame(outlink, outpicref); + if (ret < 0) + goto fail; + + ret = ff_draw_slice(outlink, 0, outlink->h, 1); + if (ret < 0) + goto fail; + + ret = ff_end_frame(outlink); +fail: avfilter_unref_buffer(movie->picref); movie->picref = NULL; - return 0; + return ret; } AVFilter avfilter_vsrc_movie = { diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 6de16768e8..22528b4650 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -130,6 +130,7 @@ static int request_frame(AVFilterLink *outlink) { TestSourceContext *test = outlink->src->priv; AVFilterBufferRef *picref; + int ret; if (test->max_pts >= 0 && test->pts > test->max_pts) return AVERROR_EOF; @@ -143,9 +144,10 @@ static int request_frame(AVFilterLink *outlink) test->nb_frame++; test->fill_picture_fn(outlink->src, picref); - ff_start_frame(outlink, picref); - ff_draw_slice(outlink, 0, test->h, 1); - ff_end_frame(outlink); + if ((ret = ff_start_frame(outlink, picref)) < 0 || + (ret = ff_draw_slice(outlink, 0, test->h, 1)) < 0 || + (ret = ff_end_frame(outlink)) < 0) + return ret; return 0; } From d515e9c2259dd825b167a94266efd5336a711702 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 09:50:49 +0200 Subject: [PATCH 05/16] vf_fps: fix a memleak on malloc failure. --- libavfilter/vf_fps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index ab7cba57d1..bf140f8143 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -161,8 +161,10 @@ static int write_to_fifo(AVFifoBuffer *fifo, AVFilterBufferRef *buf) int ret; if (!av_fifo_space(fifo) && - (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) + (ret = av_fifo_realloc2(fifo, 2*av_fifo_size(fifo)))) { + avfilter_unref_bufferp(&buf); return ret; + } av_fifo_generic_write(fifo, &buf, sizeof(buf), NULL); return 0; From 043800a96888f1a04732f12316ba477d8f098d3f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 10:07:59 +0200 Subject: [PATCH 06/16] vf_fps: add more error checks. --- libavfilter/vf_fps.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index bf140f8143..d95fef5993 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -184,7 +184,10 @@ static int end_frame(AVFilterLink *inlink) /* discard frames until we get the first timestamp */ if (s->pts == AV_NOPTS_VALUE) { if (buf->pts != AV_NOPTS_VALUE) { - write_to_fifo(s->fifo, buf); + ret = write_to_fifo(s->fifo, buf); + if (ret < 0) + return ret; + s->first_pts = s->pts = buf->pts; } else { av_log(ctx, AV_LOG_WARNING, "Discarding initial frame(s) with no " @@ -227,8 +230,20 @@ static int end_frame(AVFilterLink *inlink) /* duplicate the frame if needed */ if (!av_fifo_size(s->fifo) && i < delta - 1) { + AVFilterBufferRef *dup = avfilter_ref_buffer(buf_out, AV_PERM_READ); + av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n"); - write_to_fifo(s->fifo, avfilter_ref_buffer(buf_out, AV_PERM_READ)); + if (dup) + ret = write_to_fifo(s->fifo, dup); + else + ret = AVERROR(ENOMEM); + + if (ret < 0) { + avfilter_unref_bufferp(&buf_out); + avfilter_unref_bufferp(&buf); + return ret; + } + s->dup++; } From 02ac7311c8f1f252398b57b54992756c95f77962 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 10:12:51 +0200 Subject: [PATCH 07/16] lavfi: use avfilter_unref_bufferp() where appropriate. --- avplay.c | 12 +++--------- libavfilter/af_join.c | 4 ++-- libavfilter/fifo.c | 4 ++-- libavfilter/vf_overlay.c | 3 +-- libavfilter/vf_yadif.c | 9 ++++----- libavfilter/vsrc_movie.c | 3 +-- 6 files changed, 13 insertions(+), 22 deletions(-) diff --git a/avplay.c b/avplay.c index a42a0b48b6..ee069b58dd 100644 --- a/avplay.c +++ b/avplay.c @@ -1235,10 +1235,7 @@ static void stream_close(VideoState *is) for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) { vp = &is->pictq[i]; #if CONFIG_AVFILTER - if (vp->picref) { - avfilter_unref_buffer(vp->picref); - vp->picref = NULL; - } + avfilter_unref_bufferp(&vp->picref); #endif if (vp->bmp) { SDL_FreeYUVOverlay(vp->bmp); @@ -1287,9 +1284,7 @@ static void alloc_picture(void *opaque) SDL_FreeYUVOverlay(vp->bmp); #if CONFIG_AVFILTER - if (vp->picref) - avfilter_unref_buffer(vp->picref); - vp->picref = NULL; + avfilter_unref_bufferp(&vp->picref); vp->width = is->out_video_filter->inputs[0]->w; vp->height = is->out_video_filter->inputs[0]->h; @@ -1382,8 +1377,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t if (vp->bmp) { AVPicture pict = { { 0 } }; #if CONFIG_AVFILTER - if (vp->picref) - avfilter_unref_buffer(vp->picref); + avfilter_unref_bufferp(&vp->picref); vp->picref = src_frame->opaque; #endif diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c index 9ed11a9991..f25ec921dc 100644 --- a/libavfilter/af_join.c +++ b/libavfilter/af_join.c @@ -248,7 +248,7 @@ static void join_uninit(AVFilterContext *ctx) for (i = 0; i < ctx->nb_inputs; i++) { av_freep(&ctx->input_pads[i].name); - avfilter_unref_buffer(s->input_frames[i]); + avfilter_unref_bufferp(&s->input_frames[i]); } av_freep(&s->channels); @@ -402,7 +402,7 @@ static void join_free_buffer(AVFilterBuffer *buf) int i; for (i = 0; i < priv->nb_in_buffers; i++) - avfilter_unref_buffer(priv->in_buffers[i]); + avfilter_unref_bufferp(&priv->in_buffers[i]); av_freep(&priv->in_buffers); av_freep(&buf->priv); diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index 66de62c3b0..8264d5302e 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -65,11 +65,11 @@ static av_cold void uninit(AVFilterContext *ctx) for (buf = fifo->root.next; buf; buf = tmp) { tmp = buf->next; - avfilter_unref_buffer(buf->buf); + avfilter_unref_bufferp(&buf->buf); av_free(buf); } - avfilter_unref_buffer(fifo->buf_out); + avfilter_unref_bufferp(&fifo->buf_out); } static int add_to_queue(AVFilterLink *inlink, AVFilterBufferRef *buf) diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index a0c423de26..951ea7a4f6 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -88,8 +88,7 @@ static av_cold void uninit(AVFilterContext *ctx) { OverlayContext *over = ctx->priv; - if (over->overpicref) - avfilter_unref_buffer(over->overpicref); + avfilter_unref_bufferp(&over->overpicref); } static int query_formats(AVFilterContext *ctx) diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 9ac11bf959..1025ba12c7 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -224,8 +224,7 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) if (yadif->auto_enable && !yadif->cur->video->interlaced) { yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); - avfilter_unref_buffer(yadif->prev); - yadif->prev = NULL; + avfilter_unref_bufferp(&yadif->prev); if (yadif->out->pts != AV_NOPTS_VALUE) yadif->out->pts *= 2; return ff_start_frame(ctx->outputs[0], yadif->out); @@ -327,9 +326,9 @@ static av_cold void uninit(AVFilterContext *ctx) { YADIFContext *yadif = ctx->priv; - if (yadif->prev) avfilter_unref_buffer(yadif->prev); - if (yadif->cur ) avfilter_unref_buffer(yadif->cur ); - if (yadif->next) avfilter_unref_buffer(yadif->next); + if (yadif->prev) avfilter_unref_bufferp(&yadif->prev); + if (yadif->cur ) avfilter_unref_bufferp(&yadif->cur ); + if (yadif->next) avfilter_unref_bufferp(&yadif->next); } static int query_formats(AVFilterContext *ctx) diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index 1fb0495e82..b0f191fe8e 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -299,8 +299,7 @@ static int request_frame(AVFilterLink *outlink) ret = ff_end_frame(outlink); fail: - avfilter_unref_buffer(movie->picref); - movie->picref = NULL; + avfilter_unref_bufferp(&movie->picref); return ret; } From 785fa50f0b33bdbafebce49fec4df62f0c81eed4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 10:28:17 +0200 Subject: [PATCH 08/16] buffersrc: avoid creating unnecessary buffer reference --- libavfilter/buffersrc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index 2aa7d7d118..16a38a655e 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -323,21 +323,19 @@ static int request_frame(AVFilterLink *link) switch (link->type) { case AVMEDIA_TYPE_VIDEO: - if ((ret = ff_start_frame(link, avfilter_ref_buffer(buf, ~0))) < 0 || + if ((ret = ff_start_frame(link, buf)) < 0 || (ret = ff_draw_slice(link, 0, link->h, 1)) < 0 || (ret = ff_end_frame(link)) < 0) - goto fail; + return ret; break; case AVMEDIA_TYPE_AUDIO: - ret = ff_filter_samples(link, avfilter_ref_buffer(buf, ~0)); + ret = ff_filter_samples(link, buf); break; default: + avfilter_unref_bufferp(&buf); return AVERROR(EINVAL); } -fail: - avfilter_unref_buffer(buf); - return ret; } From 80e4ed279b3abe9f5356e2b56255b2aa64527345 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 11:00:49 +0200 Subject: [PATCH 09/16] vf_select: avoid an unnecessary avfilter_ref_buffer(). --- libavfilter/vf_select.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index d4cfbe9ceb..b4a424e1d2 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -282,11 +282,10 @@ static int request_frame(AVFilterLink *outlink) int ret; av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL); - if ((ret = ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0))) < 0 || + if ((ret = ff_start_frame(outlink, picref)) < 0 || (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 || (ret = ff_end_frame(outlink)) < 0); - avfilter_unref_buffer(picref); return ret; } From 1dc42050185d63c1de5d16146fbaee92640af187 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 11:16:53 +0200 Subject: [PATCH 10/16] lavfi: check all avfilter_ref_buffer() calls for errors. --- libavfilter/fifo.c | 3 +++ libavfilter/split.c | 17 +++++++++++++---- libavfilter/vf_delogo.c | 9 +++++++-- libavfilter/vf_frei0r.c | 9 ++++++++- libavfilter/vf_gradfun.c | 9 +++++++-- libavfilter/vf_overlay.c | 3 +++ libavfilter/vf_pixdesctest.c | 9 +++++++-- libavfilter/vf_scale.c | 14 +++++++++++--- libavfilter/vf_select.c | 6 +++++- libavfilter/vf_transpose.c | 6 +++++- libavfilter/vf_vflip.c | 3 +++ libavfilter/vf_yadif.c | 11 +++++++++-- libavfilter/video.c | 7 ++++++- libavfilter/vsrc_color.c | 9 ++++++++- libavfilter/vsrc_movie.c | 5 +++++ 15 files changed, 100 insertions(+), 20 deletions(-) diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index 8264d5302e..3226a0ddbe 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -169,6 +169,9 @@ static int return_audio_frame(AVFilterContext *ctx) queue_pop(s); } else { buf_out = avfilter_ref_buffer(head, AV_PERM_READ); + if (!buf_out) + return AVERROR(ENOMEM); + buf_out->audio->nb_samples = link->request_samples; buffer_offset(link, head, link->request_samples); } diff --git a/libavfilter/split.c b/libavfilter/split.c index 469f69d76a..084d555f1a 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -69,8 +69,11 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) int i, ret = 0; for (i = 0; i < ctx->nb_outputs; i++) { - ret = ff_start_frame(ctx->outputs[i], - avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); + AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~AV_PERM_WRITE); + if (!buf_out) + return AVERROR(ENOMEM); + + ret = ff_start_frame(ctx->outputs[i], buf_out); if (ret < 0) break; } @@ -126,8 +129,14 @@ static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref) int i, ret = 0; for (i = 0; i < ctx->nb_outputs; i++) { - ret = ff_filter_samples(inlink->dst->outputs[i], - avfilter_ref_buffer(samplesref, ~AV_PERM_WRITE)); + AVFilterBufferRef *buf_out = avfilter_ref_buffer(samplesref, + ~AV_PERM_WRITE); + if (!buf_out) { + ret = AVERROR(ENOMEM); + break; + } + + ret = ff_filter_samples(inlink->dst->outputs[i], buf_out); if (ret < 0) break; } diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index 81f33b727e..343585fc5e 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -217,7 +217,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpicref = NULL; + AVFilterBufferRef *outpicref = NULL, *for_next_filter; int ret = 0; if (inpicref->perms & AV_PERM_PRESERVE) { @@ -235,7 +235,12 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) return AVERROR(ENOMEM); } - ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + for_next_filter = avfilter_ref_buffer(outpicref, ~0); + if (for_next_filter) + ret = ff_start_frame(outlink, for_next_filter); + else + ret = AVERROR(ENOMEM); + if (ret < 0) { avfilter_unref_bufferp(&outpicref); return ret; diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index f5e9128d31..152795f5b6 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -438,13 +438,20 @@ static int source_request_frame(AVFilterLink *outlink) { Frei0rContext *frei0r = outlink->src->priv; AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + AVFilterBufferRef *buf_out; int ret; picref->video->pixel_aspect = (AVRational) {1, 1}; picref->pts = frei0r->pts++; picref->pos = -1; - ret = ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); + buf_out = avfilter_ref_buffer(picref, ~0); + if (!buf_out) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = ff_start_frame(outlink, buf_out); if (ret < 0) goto fail; diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index d73e833865..52dcb7092f 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -183,7 +183,7 @@ static int config_input(AVFilterLink *inlink) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpicref = NULL; + AVFilterBufferRef *outpicref = NULL, *for_next_filter; int ret = 0; if (inpicref->perms & AV_PERM_PRESERVE) { @@ -200,7 +200,12 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) return AVERROR(ENOMEM); } - ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + for_next_filter = avfilter_ref_buffer(outpicref, ~0); + if (for_next_filter) + ret = ff_start_frame(outlink, for_next_filter); + else + ret = AVERROR(ENOMEM); + if (ret < 0) { avfilter_unref_bufferp(&outpicref); return ret; diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 951ea7a4f6..14304c1918 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -213,6 +213,9 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) AVFilterContext *ctx = inlink->dst; OverlayContext *over = ctx->priv; + if (!outpicref) + return AVERROR(ENOMEM); + outpicref->pts = av_rescale_q(outpicref->pts, ctx->inputs[MAIN]->time_base, ctx->outputs[0]->time_base); diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c index caf0852045..11905e625c 100644 --- a/libavfilter/vf_pixdesctest.c +++ b/libavfilter/vf_pixdesctest.c @@ -55,7 +55,7 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { PixdescTestContext *priv = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFilterBufferRef *outpicref; + AVFilterBufferRef *outpicref, *for_next_filter; int i, ret = 0; outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, @@ -80,7 +80,12 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) priv->pix_desc->flags & PIX_FMT_PSEUDOPAL) memcpy(outpicref->data[1], outpicref->data[1], 256*4); - ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + for_next_filter = avfilter_ref_buffer(outpicref, ~0); + if (for_next_filter) + ret = ff_start_frame(outlink, for_next_filter); + else + ret = AVERROR(ENOMEM); + if (ret < 0) { avfilter_unref_bufferp(&outpicref); return ret; diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 73f31a65fd..66005303f5 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -256,11 +256,14 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { ScaleContext *scale = link->dst->priv; AVFilterLink *outlink = link->dst->outputs[0]; - AVFilterBufferRef *outpicref; + AVFilterBufferRef *outpicref, *for_next_filter; int ret = 0; if (!scale->sws) { - return ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); + outpicref = avfilter_ref_buffer(picref, ~0); + if (!outpicref) + return AVERROR(ENOMEM); + return ff_start_frame(outlink, outpicref); } scale->hsub = av_pix_fmt_descriptors[link->format].log2_chroma_w; @@ -281,7 +284,12 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) INT_MAX); scale->slice_y = 0; - ret = ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + for_next_filter = avfilter_ref_buffer(outpicref, ~0); + if (for_next_filter) + ret = ff_start_frame(outlink, for_next_filter); + else + ret = AVERROR(ENOMEM); + if (ret < 0) { avfilter_unref_bufferp(&outpicref); return ret; diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index b4a424e1d2..59030ebced 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -233,6 +233,7 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) select->select = select_frame(inlink->dst, picref); if (select->select) { + AVFilterBufferRef *buf_out; /* frame was requested through poll_frame */ if (select->cache_frames) { if (!av_fifo_space(select->pending_frames)) @@ -243,7 +244,10 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) sizeof(picref), NULL); return 0; } - return ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); + buf_out = avfilter_ref_buffer(picref, ~0); + if (!buf_out) + return AVERROR(ENOMEM); + return ff_start_frame(inlink->dst->outputs[0], buf_out); } return 0; diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index 49b54d760b..90f08e42cd 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -120,6 +120,7 @@ static int config_props_output(AVFilterLink *outlink) static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterLink *outlink = inlink->dst->outputs[0]; + AVFilterBufferRef *buf_out; outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); @@ -135,7 +136,10 @@ static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) outlink->out_buf->video->pixel_aspect.den = picref->video->pixel_aspect.num; } - return 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); } static int end_frame(AVFilterLink *inlink) diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c index dc7604c52a..b3143229b1 100644 --- a/libavfilter/vf_vflip.c +++ b/libavfilter/vf_vflip.c @@ -70,6 +70,9 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); int i; + if (!outpicref) + return AVERROR(ENOMEM); + for (i = 0; i < 4; i ++) { int vsub = i == 1 || i == 2 ? flip->vsub : 0; diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 1025ba12c7..db4956c2cc 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -224,14 +224,18 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) if (yadif->auto_enable && !yadif->cur->video->interlaced) { yadif->out = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); + if (!yadif->out) + return AVERROR(ENOMEM); + avfilter_unref_bufferp(&yadif->prev); if (yadif->out->pts != AV_NOPTS_VALUE) yadif->out->pts *= 2; return ff_start_frame(ctx->outputs[0], yadif->out); } - if (!yadif->prev) - yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ); + if (!yadif->prev && + !(yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ))) + return AVERROR(ENOMEM); yadif->out = ff_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE, link->w, link->h); @@ -282,6 +286,9 @@ static int request_frame(AVFilterLink *link) if (ret == AVERROR_EOF && yadif->next) { AVFilterBufferRef *next = avfilter_ref_buffer(yadif->next, AV_PERM_READ); + if (!next) + return AVERROR(ENOMEM); + next->pts = yadif->next->pts * 2 - yadif->cur->pts; start_frame(link->src->inputs[0], next); diff --git a/libavfilter/video.c b/libavfilter/video.c index 8dd5bf4272..6e5063778a 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -176,12 +176,17 @@ static int 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); - return 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; } diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index c17f54f39d..0fa6853189 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -142,13 +142,20 @@ static int color_request_frame(AVFilterLink *link) { ColorContext *color = link->src->priv; AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h); + AVFilterBufferRef *buf_out; int ret; picref->video->pixel_aspect = (AVRational) {1, 1}; picref->pts = color->pts++; picref->pos = -1; - ret = ff_start_frame(link, avfilter_ref_buffer(picref, ~0)); + buf_out = avfilter_ref_buffer(picref, ~0); + if (!buf_out) { + ret = AVERROR(ENOMEM); + goto fail; + } + + ret = ff_start_frame(link, buf_out); if (ret < 0) goto fail; diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index b0f191fe8e..926d57dff5 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -289,6 +289,11 @@ static int request_frame(AVFilterLink *outlink) return ret; outpicref = avfilter_ref_buffer(movie->picref, ~0); + if (!outpicref) { + ret = AVERROR(ENOMEM); + goto fail; + } + ret = ff_start_frame(outlink, outpicref); if (ret < 0) goto fail; From 8f3a3ce7307e39a030db3bf8d2e525b21e039ca2 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 11:16:53 +0200 Subject: [PATCH 11/16] lavfi: check all ff_get_video_buffer() calls for errors. --- libavfilter/buffersrc.c | 3 +++ libavfilter/vf_frei0r.c | 3 +++ libavfilter/vf_pad.c | 3 +++ libavfilter/vf_vflip.c | 3 +++ libavfilter/vf_yadif.c | 5 +++++ libavfilter/vsrc_color.c | 3 +++ libavfilter/vsrc_testsrc.c | 3 +++ 7 files changed, 23 insertions(+) diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index 16a38a655e..c0cc3a3fff 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -92,6 +92,9 @@ int av_buffersrc_write_frame(AVFilterContext *buffer_filter, AVFrame *frame) frame->format); buf = ff_get_video_buffer(buffer_filter->outputs[0], AV_PERM_WRITE, c->w, c->h); + if (!buf) + return AVERROR(ENOMEM); + av_image_copy(buf->data, buf->linesize, frame->data, frame->linesize, c->pix_fmt, c->w, c->h); break; diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 152795f5b6..606c5e2d32 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -441,6 +441,9 @@ static int source_request_frame(AVFilterLink *outlink) AVFilterBufferRef *buf_out; int ret; + if (!picref) + return AVERROR(ENOMEM); + picref->video->pixel_aspect = (AVRational) {1, 1}; picref->pts = frei0r->pts++; picref->pos = -1; diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 262a416488..ed2e2e0891 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -262,6 +262,9 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int h + (pad->h - pad->in_h)); int plane; + if (!picref) + return NULL; + picref->video->w = w; picref->video->h = h; diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c index b3143229b1..f0fb32aadc 100644 --- a/libavfilter/vf_vflip.c +++ b/libavfilter/vf_vflip.c @@ -52,6 +52,9 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, return ff_default_get_video_buffer(link, perms, w, h); picref = ff_get_video_buffer(link->dst->outputs[0], perms, w, h); + if (!picref) + return NULL; + for (i = 0; i < 4; i ++) { int vsub = i == 1 || i == 2 ? flip->vsub : 0; diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index db4956c2cc..c6d78a5ae9 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -173,6 +173,9 @@ static int return_frame(AVFilterContext *ctx, int is_second) if (is_second) { yadif->out = ff_get_video_buffer(link, AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE, link->w, link->h); + if (!yadif->out) + return AVERROR(ENOMEM); + avfilter_copy_buffer_ref_props(yadif->out, yadif->cur); yadif->out->video->interlaced = 0; } @@ -239,6 +242,8 @@ static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) yadif->out = ff_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE | AV_PERM_REUSE, link->w, link->h); + if (!yadif->out) + return AVERROR(ENOMEM); avfilter_copy_buffer_ref_props(yadif->out, yadif->cur); yadif->out->video->interlaced = 0; diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index 0fa6853189..ec83f03c5c 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -145,6 +145,9 @@ static int color_request_frame(AVFilterLink *link) AVFilterBufferRef *buf_out; int ret; + if (!picref) + return AVERROR(ENOMEM); + picref->video->pixel_aspect = (AVRational) {1, 1}; picref->pts = color->pts++; picref->pos = -1; diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 22528b4650..42cd58ed89 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -135,6 +135,9 @@ static int request_frame(AVFilterLink *outlink) if (test->max_pts >= 0 && test->pts > test->max_pts) return AVERROR_EOF; picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h); + if (!picref) + return AVERROR(ENOMEM); + picref->pts = test->pts++; picref->pos = -1; picref->video->key_frame = 1; From a8a2271fe0bda50a573cdd287bf644ecff1a61c9 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 15 Jul 2012 11:29:10 +0200 Subject: [PATCH 12/16] buffersrc: check ff_get_audio_buffer() for errors. --- libavfilter/buffersrc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index c0cc3a3fff..33cb63b46b 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -103,6 +103,9 @@ int av_buffersrc_write_frame(AVFilterContext *buffer_filter, AVFrame *frame) frame->format); buf = ff_get_audio_buffer(buffer_filter->outputs[0], AV_PERM_WRITE, frame->nb_samples); + if (!buf) + return AVERROR(ENOMEM); + av_samples_copy(buf->extended_data, frame->extended_data, 0, 0, frame->nb_samples, av_get_channel_layout_nb_channels(frame->channel_layout), From 721113bed22e51dca52bc1a486b7c24be9d3b52d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 21 Jul 2012 10:48:39 +0200 Subject: [PATCH 13/16] matroskadec: return more correct error code on read error. --- libavformat/matroskadec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 40c2eb10dd..c454713eeb 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -597,8 +597,9 @@ static int ebml_read_num(MatroskaDemuxContext *matroska, AVIOContext *pb, av_log(matroska->ctx, AV_LOG_ERROR, "Read error at pos. %"PRIu64" (0x%"PRIx64")\n", pos, pos); + return pb->error ? pb->error : AVERROR(EIO); } - return AVERROR(EIO); /* EOS or actual I/O error */ + return AVERROR_EOF; } /* get the length of the EBML number */ From 73cd131ebc3a735d27aea945628686e0f450eaa3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 5 Jul 2012 10:28:28 +0200 Subject: [PATCH 14/16] FATE: add a test for the asyncts audio filter. --- tests/Makefile | 1 + tests/fate/filter.mak | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 tests/fate/filter.mak diff --git a/tests/Makefile b/tests/Makefile index 91f2d49b19..63cf1f2f23 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -42,6 +42,7 @@ include $(SRC_PATH)/tests/fate/demux.mak include $(SRC_PATH)/tests/fate/dfa.mak include $(SRC_PATH)/tests/fate/dpcm.mak include $(SRC_PATH)/tests/fate/ea.mak +include $(SRC_PATH)/tests/fate/filter.mak include $(SRC_PATH)/tests/fate/flac.mak include $(SRC_PATH)/tests/fate/fft.mak include $(SRC_PATH)/tests/fate/h264.mak diff --git a/tests/fate/filter.mak b/tests/fate/filter.mak new file mode 100644 index 0000000000..d547d3bd7f --- /dev/null +++ b/tests/fate/filter.mak @@ -0,0 +1,10 @@ +FATE_ASYNCTS += fate-filter-asyncts +fate-filter-asyncts: SRC = $(SAMPLES)/nellymoser/nellymoser-discont.flv +fate-filter-asyncts: CMD = md5 -i $(SRC) -af asyncts -f wav +fate-filter-asyncts: CMP = oneline +fate-filter-asyncts: REF = 5faa5d6ecec8d0c982e80a090d114576 + +FATE_FILTER += $(FATE_ASYNCTS) +FATE_SAMPLES_AVCONV += $(FATE_ASYNCTS) + +fate-filter: $(FATE_FILTER) From 6bd37e0b283dd3b04d13d98ce05b33dbf6a53993 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sun, 22 Jul 2012 01:12:24 +0200 Subject: [PATCH 15/16] build: Drop gcc-specific warning flag from header compilation rule The flag was added to avoid excessive warning spam, but nowadays those warnings no longer occur in such large numbers as to require silencing. Besides, gcc-specific flags do not belong in the Makefiles. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 28568f98c7..478ffcab4b 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ COMPILE_S = $(call COMPILE,AS) $(COMPILE_S) %.ho: %.h - $(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused -c -o $@ -x c $< + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ -x c $< %.ver: %.v $(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@ From df53a4a7c1c496363e3fc165b431940ccd0cb8a0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 Jul 2012 11:29:06 +0200 Subject: [PATCH 16/16] FATE: fix the asyncts test Nellymoser is float, so use oneoff comparison instead of md5. --- tests/fate/filter.mak | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/fate/filter.mak b/tests/fate/filter.mak index d547d3bd7f..41916c9b35 100644 --- a/tests/fate/filter.mak +++ b/tests/fate/filter.mak @@ -1,8 +1,8 @@ FATE_ASYNCTS += fate-filter-asyncts fate-filter-asyncts: SRC = $(SAMPLES)/nellymoser/nellymoser-discont.flv -fate-filter-asyncts: CMD = md5 -i $(SRC) -af asyncts -f wav -fate-filter-asyncts: CMP = oneline -fate-filter-asyncts: REF = 5faa5d6ecec8d0c982e80a090d114576 +fate-filter-asyncts: CMD = pcm -i $(SRC) -af asyncts +fate-filter-asyncts: CMP = oneoff +fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont.pcm FATE_FILTER += $(FATE_ASYNCTS) FATE_SAMPLES_AVCONV += $(FATE_ASYNCTS)