diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-07-22 22:57:02 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-07-22 23:56:21 +0200 |
commit | 88beb2df982aa4de257f742ff41f777927cc5173 (patch) | |
tree | 15427851afeaa2fee531f53808237948b81b2e44 | |
parent | 9023de342f88e961a3741753aff68925eebf884e (diff) | |
parent | df53a4a7c1c496363e3fc165b431940ccd0cb8a0 (diff) | |
download | ffmpeg-88beb2df982aa4de257f742ff41f777927cc5173.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
FATE: fix the asyncts test
build: Drop gcc-specific warning flag from header compilation rule
FATE: add a test for the asyncts audio filter.
matroskadec: return more correct error code on read error.
buffersrc: check ff_get_audio_buffer() for errors.
lavfi: check all ff_get_video_buffer() calls for errors.
lavfi: check all avfilter_ref_buffer() calls for errors.
vf_select: avoid an unnecessary avfilter_ref_buffer().
buffersrc: avoid creating unnecessary buffer reference
lavfi: use avfilter_unref_bufferp() where appropriate.
vf_fps: add more error checks.
vf_fps: fix a memleak on malloc failure.
lavfi: check all ff_start_frame/draw_slice/end_frame calls for errors
lavfi: add error handling to end_frame().
lavfi: add error handling to draw_slice().
lavfi: add error handling to start_frame().
Conflicts:
Makefile
ffplay.c
libavfilter/buffersrc.c
libavfilter/vf_boxblur.c
libavfilter/vf_drawtext.c
libavfilter/vf_fade.c
libavfilter/vf_frei0r.c
libavfilter/vf_hflip.c
libavfilter/vf_overlay.c
libavfilter/vf_pad.c
libavfilter/vf_scale.c
libavfilter/video.c
libavfilter/vsrc_color.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
64 files changed, 764 insertions, 376 deletions
diff --git a/common.mak b/common.mak index e306cefba6..5e43c7dd1b 100644 --- a/common.mak +++ b/common.mak @@ -54,7 +54,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)/' $^ > $@ 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/avfilter.h b/libavfilter/avfilter.h index 4d3a7a82d1..229f78d8e9 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -261,8 +261,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 @@ -287,16 +290,20 @@ 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 * 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 @@ -385,7 +392,7 @@ enum AVMediaType avfilter_pad_get_type(AVFilterPad *pads, int pad_idx); /** default handler for end_frame() for video inputs */ attribute_deprecated -void avfilter_default_end_frame(AVFilterLink *link); +int avfilter_default_end_frame(AVFilterLink *link); /** * Filter definition. This defines the pads a filter contains, and all the diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 5e5e8e761d..e00af7c151 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/buffersrc.c b/libavfilter/buffersrc.c index d60a1b8bb8..5186b0920b 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -382,19 +382,19 @@ 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, buf)) < 0 || + (ret = ff_draw_slice(link, 0, link->h, 1)) < 0 || + (ret = ff_end_frame(link)) < 0) + 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); } - avfilter_unref_buffer(buf); - return ret; } diff --git a/libavfilter/f_settb.c b/libavfilter/f_settb.c index 9aed96468d..033e1f7173 100644 --- a/libavfilter/f_settb.c +++ b/libavfilter/f_settb.c @@ -99,7 +99,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]; @@ -113,7 +113,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) } inlink->cur_buf = NULL; - ff_start_frame(outlink, picref); + return ff_start_frame(outlink, picref); } static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples) diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index df7962482e..4e0e87f83d 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -65,17 +65,18 @@ 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) { 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; @@ -103,9 +98,15 @@ 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 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. @@ -168,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); } @@ -240,9 +244,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: @@ -272,7 +278,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 5f0299cb83..c217883319 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -93,6 +93,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); @@ -119,16 +122,20 @@ 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 * 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/sink_buffer.c b/libavfilter/sink_buffer.c index 31e0a98772..f7b16db50a 100644 --- a/libavfilter/sink_buffer.c +++ b/libavfilter/sink_buffer.c @@ -96,7 +96,7 @@ static av_cold void common_uninit(AVFilterContext *ctx) } } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; BufferSinkContext *buf = inlink->dst->priv; @@ -108,7 +108,7 @@ static void end_frame(AVFilterLink *inlink) av_log(ctx, AV_LOG_ERROR, "Cannot buffer more frames. Consume some available frames " "before adding new ones.\n"); - return; + return AVERROR(ENOMEM); } } @@ -124,6 +124,7 @@ static void end_frame(AVFilterLink *inlink) (char *)av_x_if_null(ctx->name, ctx->filter->name)); buf->warning_limit *= 10; } + return 0; } void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size) diff --git a/libavfilter/split.c b/libavfilter/split.c index ce03a08275..85377c1f31 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -63,32 +63,47 @@ 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++) { + 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; + } + 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) +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 = { @@ -114,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/src_movie.c b/libavfilter/src_movie.c index ee68eca7d8..cb65dd6877 100644 --- a/libavfilter/src_movie.c +++ b/libavfilter/src_movie.c @@ -326,13 +326,24 @@ static int movie_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); - avfilter_unref_buffer(movie->picref); - movie->picref = NULL; + if (!outpicref) { + ret = AVERROR(ENOMEM); + goto fail; + } - return 0; + 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_bufferp(&movie->picref); + + return ret; } AVFilter avfilter_vsrc_movie = { diff --git a/libavfilter/vf_alphaextract.c b/libavfilter/vf_alphaextract.c index 06cbb71315..f6ce1b3a78 100644 --- a/libavfilter/vf_alphaextract.c +++ b/libavfilter/vf_alphaextract.c @@ -59,7 +59,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) { AlphaExtractContext *extract = inlink->dst->priv; AVFilterBufferRef *cur_buf = inlink->cur_buf; @@ -91,7 +91,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir) linesize); } } - ff_draw_slice(inlink->dst->outputs[0], y0, h, slice_dir); + return ff_draw_slice(inlink->dst->outputs[0], y0, h, slice_dir); } AVFilter avfilter_vf_alphaextract = { diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c index 67422a1df1..278f9a3e03 100644 --- a/libavfilter/vf_alphamerge.c +++ b/libavfilter/vf_alphamerge.c @@ -95,8 +95,8 @@ static int config_output(AVFilterLink *outlink) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) {} -static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) {} +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) {return 0;} +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) {return 0;} static void draw_frame(AVFilterContext *ctx, AVFilterBufferRef *main_buf, @@ -130,7 +130,7 @@ static void draw_frame(AVFilterContext *ctx, ff_draw_slice(ctx->outputs[0], 0, h, 1); } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AlphaMergeContext *merge = ctx->priv; @@ -157,6 +157,7 @@ static void end_frame(AVFilterLink *inlink) ff_end_frame(ctx->outputs[0]); avfilter_unref_buffer(alpha_buf); } + return 0; } static int request_frame(AVFilterLink *outlink) diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c index 584ea9c96a..e4ca5d5484 100644 --- a/libavfilter/vf_aspect.c +++ b/libavfilter/vf_aspect.c @@ -51,13 +51,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->sample_aspect_ratio = aspect->ratio; 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_ass.c b/libavfilter/vf_ass.c index e7f2fe1fce..a40f93cc67 100644 --- a/libavfilter/vf_ass.c +++ b/libavfilter/vf_ass.c @@ -157,7 +157,7 @@ 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; } /* libass stores an RGBA color in the format RRGGBBTT, where TT is the transparency level */ #define AR(c) ( (c)>>24) @@ -180,7 +180,7 @@ static void overlay_ass_image(AssContext *ass, AVFilterBufferRef *picref, } } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; @@ -197,7 +197,7 @@ static void end_frame(AVFilterLink *inlink) overlay_ass_image(ass, picref, image); ff_draw_slice(outlink, 0, picref->video->h, 1); - ff_end_frame(outlink); + return ff_end_frame(outlink); } AVFilter avfilter_vf_ass = { diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c index 47d4709dc4..b59d1bc3a8 100644 --- a/libavfilter/vf_bbox.c +++ b/libavfilter/vf_bbox.c @@ -56,7 +56,7 @@ static int query_formats(AVFilterContext *ctx) return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; BBoxContext *bbox = ctx->priv; @@ -86,7 +86,7 @@ static void end_frame(AVFilterLink *inlink) av_log(ctx, AV_LOG_INFO, "\n"); bbox->frame++; - ff_end_frame(inlink->dst->outputs[0]); + return ff_end_frame(inlink->dst->outputs[0]); } AVFilter avfilter_vf_bbox = { diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c index cd35297845..dfd94efca2 100644 --- a/libavfilter/vf_blackdetect.c +++ b/libavfilter/vf_blackdetect.c @@ -146,7 +146,7 @@ static int request_frame(AVFilterLink *outlink) 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; BlackDetectContext *blackdetect = ctx->priv; @@ -160,10 +160,10 @@ 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) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; BlackDetectContext *blackdetect = ctx->priv; @@ -194,7 +194,7 @@ static void end_frame(AVFilterLink *inlink) blackdetect->last_picref_pts = picref->pts; blackdetect->frame_count++; blackdetect->nb_black_pixels = 0; - ff_end_frame(inlink->dst->outputs[0]); + return ff_end_frame(inlink->dst->outputs[0]); } AVFilter avfilter_vf_blackdetect = { diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index 7d0c2d6d51..dc3344489a 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -77,7 +77,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; @@ -91,10 +91,10 @@ 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) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; BlackFrameContext *blackframe = ctx->priv; @@ -114,7 +114,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_boxblur.c b/libavfilter/vf_boxblur.c index aee805ab1f..e98e90aba6 100644 --- a/libavfilter/vf_boxblur.c +++ b/libavfilter/vf_boxblur.c @@ -301,9 +301,9 @@ static void vblur(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_li h, radius, power, temp); } -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) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; BoxBlurContext *boxblur = ctx->priv; @@ -328,7 +328,7 @@ static void end_frame(AVFilterLink *inlink) boxblur->temp); ff_draw_slice(outlink, 0, inlink->h, 1); - avfilter_default_end_frame(inlink); + return avfilter_default_end_frame(inlink); } AVFilter avfilter_vf_boxblur = { diff --git a/libavfilter/vf_colormatrix.c b/libavfilter/vf_colormatrix.c index d6f6dbd721..bb66bd3d6a 100644 --- a/libavfilter/vf_colormatrix.c +++ b/libavfilter/vf_colormatrix.c @@ -340,7 +340,7 @@ static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int return picref; } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { AVFilterContext *ctx = link->dst; ColorMatrixContext *color = ctx->priv; @@ -348,10 +348,10 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) color->outpicref = outpicref; - ff_start_frame(link->dst->outputs[0], outpicref); + return ff_start_frame(link->dst->outputs[0], outpicref); } -static void end_frame(AVFilterLink *link) +static int end_frame(AVFilterLink *link) { AVFilterContext *ctx = link->dst; ColorMatrixContext *color = ctx->priv; @@ -365,10 +365,10 @@ static void end_frame(AVFilterLink *link) process_frame_uyvy422(color, out, link->cur_buf); ff_draw_slice(ctx->outputs[0], 0, link->dst->outputs[0]->h, 1); - ff_end_frame(ctx->outputs[0]); + return ff_end_frame(ctx->outputs[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_colormatrix = { .name = "colormatrix", diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index f9e17573a4..4d3a7f355a 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -259,7 +259,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; @@ -267,6 +267,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; @@ -310,16 +313,16 @@ 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) +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; @@ -328,15 +331,15 @@ 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) +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 da2973223e..b245d6e12b 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 14158ed92d..8b9f29d959 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -209,27 +209,48 @@ 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, *for_next_filter; + 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); + } + + 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; + } 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) { } +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]; @@ -239,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; @@ -253,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_deshake.c b/libavfilter/vf_deshake.c index 70d7fe91bc..0a1d865e56 100644 --- a/libavfilter/vf_deshake.c +++ b/libavfilter/vf_deshake.c @@ -425,7 +425,7 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&deshake->avctx); } -static void end_frame(AVFilterLink *link) +static int end_frame(AVFilterLink *link) { DeshakeContext *deshake = link->dst->priv; AVFilterBufferRef *in = link->cur_buf; @@ -529,11 +529,12 @@ static void end_frame(AVFilterLink *link) // Draw the transformed frame information ff_draw_slice(link->dst->outputs[0], 0, link->h, 1); - ff_end_frame(link->dst->outputs[0]); + return 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_deshake = { diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c index 15f21fc961..8be8b14a05 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 43e2b463f9..ac619428ef 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -780,14 +780,18 @@ 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 void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; DrawTextContext *dtext = ctx->priv; AVFilterBufferRef *picref = inlink->cur_buf; + int ret; dtext->var_values[VAR_T] = picref->pts == AV_NOPTS_VALUE ? NAN : picref->pts * av_q2d(inlink->time_base); @@ -801,8 +805,10 @@ static void end_frame(AVFilterLink *inlink) 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 ecec1bc735..6d68357e6a 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -214,7 +214,7 @@ static void fade_plane(int y, int h, int w, } } -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; @@ -255,20 +255,23 @@ 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) +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 4da1195b65..6573ac8d77 100644 --- a/libavfilter/vf_fieldorder.c +++ b/libavfilter/vf_fieldorder.c @@ -116,21 +116,35 @@ 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) +static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterContext *ctx = inlink->dst; FieldOrderContext *fieldorder = ctx->priv; @@ -144,11 +158,12 @@ 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) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; FieldOrderContext *fieldorder = ctx->priv; @@ -212,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 71c30ccdff..3fdac4f267 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; @@ -159,28 +161,33 @@ 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; } -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++; /* 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 " @@ -188,13 +195,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 +217,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 */ @@ -224,31 +230,51 @@ static void 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++; } 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); - 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 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) +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 d165a5405a..0292f56477 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -340,20 +340,26 @@ 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) +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 = { @@ -432,18 +438,38 @@ 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; + + if (!picref) + return AVERROR(ENOMEM); + picref->video->sample_aspect_ratio = (AVRational) {1, 1}; picref->pts = frei0r->pts++; picref->pos = -1; - 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; + 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_gradfun.c b/libavfilter/vf_gradfun.c index 45699bcd89..e540e51964 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -180,32 +180,53 @@ 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, *for_next_filter; + 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); + } + + 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; + } 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) { } +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; @@ -223,8 +244,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_hflip.c b/libavfilter/vf_hflip.c index ebb732ca06..413c5668f1 100644 --- a/libavfilter/vf_hflip.c +++ b/libavfilter/vf_hflip.c @@ -83,7 +83,7 @@ static int config_props(AVFilterLink *inlink) return 0; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterLink *outlink = inlink->dst->outputs[0]; @@ -95,10 +95,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) if (av_pix_fmt_descriptors[inlink->format].flags & PIX_FMT_PAL) memcpy(inlink->dst->outputs[0]->out_buf->data[1], picref->data[1], AVPALETTE_SIZE); - 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 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; @@ -159,7 +159,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 0b12ab4185..cb46c5b6ce 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -290,9 +290,12 @@ 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) +static int end_frame(AVFilterLink *inlink) { HQDN3DContext *hqdn3d = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; @@ -300,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, @@ -320,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_idet.c b/libavfilter/vf_idet.c index d192be72f3..02d073d492 100644 --- a/libavfilter/vf_idet.c +++ b/libavfilter/vf_idet.c @@ -169,7 +169,7 @@ static void filter(AVFilterContext *ctx) av_log(ctx, AV_LOG_DEBUG, "Single frame:%s, Multi frame:%s\n", type2str(type), type2str(idet->last_type)); } -static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { AVFilterContext *ctx = link->dst; IDETContext *idet = ctx->priv; @@ -181,21 +181,21 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) idet->next = picref; if (!idet->cur) - return; + return 0; if (!idet->prev) idet->prev = avfilter_ref_buffer(idet->cur, AV_PERM_READ); - ff_start_frame(ctx->outputs[0], avfilter_ref_buffer(idet->cur, AV_PERM_READ)); + return ff_start_frame(ctx->outputs[0], avfilter_ref_buffer(idet->cur, AV_PERM_READ)); } -static void end_frame(AVFilterLink *link) +static int end_frame(AVFilterLink *link) { AVFilterContext *ctx = link->dst; IDETContext *idet = ctx->priv; if (!idet->cur) - return; + return 0; if (!idet->csp) idet->csp = &av_pix_fmt_descriptors[link->format]; @@ -205,7 +205,7 @@ static void end_frame(AVFilterLink *link) filter(ctx); ff_draw_slice(ctx->outputs[0], 0, link->h, 1); - ff_end_frame(ctx->outputs[0]); + return ff_end_frame(ctx->outputs[0]); } static int request_frame(AVFilterLink *link) @@ -311,7 +311,7 @@ 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; } AVFilter avfilter_vf_idet = { .name = "idet", diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index ab33686b46..fa1604114c 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; @@ -351,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; @@ -359,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_lut.c b/libavfilter/vf_lut.c index 7ceee514c9..a9b9e8aaec 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -275,7 +275,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; @@ -332,7 +332,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_mp.c b/libavfilter/vf_mp.c index 8ae89475b1..4fa02c773a 100644 --- a/libavfilter/vf_mp.c +++ b/libavfilter/vf_mp.c @@ -848,15 +848,17 @@ static int request_frame(AVFilterLink *outlink) return ret; } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, 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 void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { MPContext *m = inlink->dst->priv; AVFilterBufferRef *inpic = inlink->cur_buf; @@ -883,6 +885,7 @@ static void end_frame(AVFilterLink *inlink) av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n"); } free_mp_image(mpi); + return 0; } AVFilter avfilter_vf_mp = { diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 57cef6f1ea..935274f06d 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -145,8 +145,7 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&over->x_expr); av_freep(&over->y_expr); - if (over->overpicref) - avfilter_unref_bufferp(&over->overpicref); + avfilter_unref_bufferp(&over->overpicref); ff_bufqueue_discard_all(&over->queue_main); ff_bufqueue_discard_all(&over->queue_over); } @@ -506,7 +505,7 @@ static void flush_frames(AVFilterContext *ctx) while (!try_push_frame(ctx)); } -static void start_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterContext *ctx = inlink->dst; OverlayContext *over = ctx->priv; @@ -519,9 +518,10 @@ static void start_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref) av_assert1(inpicref == inlink->cur_buf); inlink->cur_buf = NULL; } + return 0; } -static void draw_slice_main(AVFilterLink *inlink, int y, int h, int slice_dir) +static int draw_slice_main(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterContext *ctx = inlink->dst; OverlayContext *over = ctx->priv; @@ -536,10 +536,10 @@ static void draw_slice_main(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_main(AVFilterLink *inlink) +static int end_frame_main(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; @@ -547,15 +547,16 @@ static void end_frame_main(AVFilterLink *inlink) flush_frames(ctx); if (!outpicref) - return; - ff_end_frame(ctx->outputs[0]); + return 0; + return ff_end_frame(ctx->outputs[0]); } -static void start_frame_over(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame_over(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { + return 0; } -static void end_frame_over(AVFilterLink *inlink) +static int end_frame_over(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; OverlayContext *over = ctx->priv; @@ -566,7 +567,7 @@ static void end_frame_over(AVFilterLink *inlink) inpicref->pts = av_rescale_q(inpicref->pts, ctx->inputs[OVERLAY]->time_base, ctx->outputs[0]->time_base); ff_bufqueue_add(ctx, &over->queue_over, inpicref); - try_push_frame(ctx); + return try_push_frame(ctx); } static int request_frame(AVFilterLink *outlink) @@ -597,7 +598,10 @@ static int request_frame(AVFilterLink *outlink) 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; +} AVFilter avfilter_vf_overlay = { .name = "overlay", diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index e88ea1348b..3e9dfa2680 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -226,6 +226,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; @@ -259,12 +262,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] && pad->draw.pixelstep[plane]; plane++) { int hsub = pad->draw.hsub[plane]; @@ -292,22 +298,37 @@ 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 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 */ @@ -324,15 +345,17 @@ static void draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, link->dst->outputs[0]->out_buf->data, link->dst->outputs[0]->out_buf->linesize, 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; @@ -340,7 +363,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) h = ff_draw_round_to_sub(&pad->draw, 1, -1, h); if (!h) - return; + return 0; draw_send_bar_slice(link, y, h, slice_dir, 1); /* left border */ @@ -357,9 +380,11 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) /* right border */ ff_fill_rectangle(&pad->draw, &pad->color, outpic->data, outpic->linesize, 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 12a6a2f98a..2e09d8c6a7 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; + AVFilterBufferRef *outpicref, *for_next_filter; + 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,10 +80,22 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) priv->pix_desc->flags & PIX_FMT_PSEUDOPAL) memcpy(outpicref->data[1], picref->data[1], AVPALETTE_SIZE); - 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; + } + + outlink->out_buf = outpicref; + 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; @@ -108,7 +122,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_removelogo.c b/libavfilter/vf_removelogo.c index df67193fd3..7b0a662b92 100644 --- a/libavfilter/vf_removelogo.c +++ b/libavfilter/vf_removelogo.c @@ -472,7 +472,7 @@ static void blur_image(int ***mask, } } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *outpicref; @@ -487,10 +487,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref = inpicref; outlink->out_buf = outpicref; - ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + return ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { RemovelogoContext *removelogo = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; @@ -515,7 +515,7 @@ static void end_frame(AVFilterLink *inlink) inlink->w/2, inlink->h/2, direct, &removelogo->half_mask_bbox); ff_draw_slice(outlink, 0, inlink->h, 1); - ff_end_frame(outlink); + return ff_end_frame(outlink); } static void uninit(AVFilterContext *ctx) @@ -540,7 +540,7 @@ static void uninit(AVFilterContext *ctx) } } -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_removelogo = { .name = "removelogo", diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 9b9ddaf8b2..143ff70951 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -272,11 +272,12 @@ 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; + AVFilterBufferRef *outpicref, *for_next_filter; + int ret = 0; if( picref->video->w != link->w || picref->video->h != link->h @@ -295,19 +296,23 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) if (!scale->sws) { - ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); - return; + 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; scale->vsub = av_pix_fmt_descriptors[link->format].log2_chroma_h; outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, 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; if(scale->output_is_pal) ff_set_systematic_pal2(outpicref->data[1], outlink->format == PIX_FMT_PAL8 ? PIX_FMT_BGR8 : outlink->format); @@ -317,7 +322,19 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) INT_MAX); scale->slice_y = 0; - 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; + } + + outlink->out_buf = outpicref; + return 0; } static int scale_slice(AVFilterLink *link, struct SwsContext *sws, int y, int h, int mul, int field) @@ -346,14 +363,13 @@ static int scale_slice(AVFilterLink *link, struct SwsContext *sws, int y, int h, out,out_stride); } -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; 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) @@ -369,9 +385,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 1fa395e055..4d19b33913 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -269,12 +269,13 @@ 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; 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)) @@ -283,29 +284,36 @@ 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)); + 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; } -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) +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) @@ -317,12 +325,14 @@ 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); - avfilter_unref_buffer(picref); - return 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); + + return ret; } while (!select->select) { diff --git a/libavfilter/vf_setfield.c b/libavfilter/vf_setfield.c index 4be4fd89da..93d30c7b0b 100644 --- a/libavfilter/vf_setfield.c +++ b/libavfilter/vf_setfield.c @@ -69,7 +69,7 @@ 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) { SetFieldContext *setfield = inlink->dst->priv; AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); @@ -80,7 +80,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref->video->interlaced = 1; outpicref->video->top_field_first = setfield->mode; } - ff_start_frame(inlink->dst->outputs[0], outpicref); + return ff_start_frame(inlink->dst->outputs[0], outpicref); } AVFilter avfilter_vf_setfield = { diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c index cef467ac1a..4e2c8f83b9 100644 --- a/libavfilter/vf_setpts.c +++ b/libavfilter/vf_setpts.c @@ -92,12 +92,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); @@ -121,7 +124,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_showinfo.c b/libavfilter/vf_showinfo.c index 3622f09696..1c655636b3 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -41,7 +41,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; @@ -81,7 +81,7 @@ static void end_frame(AVFilterLink *inlink) av_log(ctx, AV_LOG_INFO, "]\n"); 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_slicify.c b/libavfilter/vf_slicify.c index f1f6a0d455..e7679a0527 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,27 +75,34 @@ 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) +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_super2xsai.c b/libavfilter/vf_super2xsai.c index cbd9fcbff8..0b48155b12 100644 --- a/libavfilter/vf_super2xsai.c +++ b/libavfilter/vf_super2xsai.c @@ -302,9 +302,9 @@ static int config_output(AVFilterLink *outlink) 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) +static int end_frame(AVFilterLink *inlink) { AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *inpicref = inlink->cur_buf; @@ -315,7 +315,7 @@ static void end_frame(AVFilterLink *inlink) inlink->w, inlink->h); ff_draw_slice(outlink, 0, outlink->h, 1); - ff_end_frame(outlink); + return ff_end_frame(outlink); } AVFilter avfilter_vf_super2xsai = { diff --git a/libavfilter/vf_swapuv.c b/libavfilter/vf_swapuv.c index 1a13edae5d..94015d9811 100644 --- a/libavfilter/vf_swapuv.c +++ b/libavfilter/vf_swapuv.c @@ -46,7 +46,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) { AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); @@ -56,7 +56,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) outpicref->linesize[1] = inpicref->linesize[2]; outpicref->linesize[2] = inpicref->linesize[1]; - ff_start_frame(link->dst->outputs[0], outpicref); + return ff_start_frame(link->dst->outputs[0], outpicref); } static int query_formats(AVFilterContext *ctx) diff --git a/libavfilter/vf_thumbnail.c b/libavfilter/vf_thumbnail.c index 4359635c1f..8e73de920f 100644 --- a/libavfilter/vf_thumbnail.c +++ b/libavfilter/vf_thumbnail.c @@ -68,7 +68,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) { int i, j; AVFilterContext *ctx = inlink->dst; @@ -86,6 +86,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } p += picref->linesize[0]; } + return 0; } /** @@ -106,7 +107,7 @@ static double frame_sum_square_err(const int *hist, const double *median) return sum_sq_err; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { int i, j, best_frame_idx = 0; double avg_hist[HIST_SIZE] = {0}, sq_err, min_sq_err = -1; @@ -122,7 +123,7 @@ static void end_frame(AVFilterLink *inlink) // no selection until the buffer of N frames is filled up if (thumb->n < thumb->n_frames - 1) { thumb->n++; - return; + return 0; } // average histogram of the N frames @@ -156,7 +157,7 @@ static void end_frame(AVFilterLink *inlink) ff_start_frame(outlink, picref); thumb->frames[best_frame_idx].buf = NULL; ff_draw_slice(outlink, 0, inlink->h, 1); - ff_end_frame(outlink); + return ff_end_frame(outlink); } static av_cold void uninit(AVFilterContext *ctx) @@ -170,7 +171,7 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&thumb->frames); } -static void null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { } +static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { return 0; } static int request_frame(AVFilterLink *link) { diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c index 8ed7333886..a6c7e7a3ef 100644 --- a/libavfilter/vf_tile.c +++ b/libavfilter/vf_tile.c @@ -96,23 +96,23 @@ static int config_props(AVFilterLink *outlink) * buffers are fed to start_frame in the order they were obtained from * get_buffer (think B-frames). */ -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterContext *ctx = inlink->dst; TileContext *tile = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; if (tile->current) - return; + return 0; outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); avfilter_copy_buffer_ref_props(outlink->out_buf, picref); outlink->out_buf->video->w = outlink->w; outlink->out_buf->video->h = outlink->h; - ff_start_frame(outlink, outlink->out_buf); + return ff_start_frame(outlink, outlink->out_buf); } -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; TileContext *tile = ctx->priv; @@ -126,6 +126,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) x0, y0 + y, 0, y, inlink->cur_buf->video->w, h); /* TODO if tile->w == 1 && slice_dir is always 1, we could draw_slice * immediately. */ + return 0; } static void draw_blank_frame(AVFilterContext *ctx) @@ -153,14 +154,15 @@ static void end_last_frame(AVFilterContext *ctx) tile->current = 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; TileContext *tile = ctx->priv; - avfilter_unref_buffer(inlink->cur_buf); + avfilter_unref_bufferp(&inlink->cur_buf); if (++tile->current == tile->w * tile->h) end_last_frame(ctx); + return 0; } static int request_frame(AVFilterLink *outlink) diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c index d511d72667..559f64b25b 100644 --- a/libavfilter/vf_tinterlace.c +++ b/libavfilter/vf_tinterlace.c @@ -198,7 +198,7 @@ void copy_picture_field(uint8_t *dst[4], int dst_linesize[4], } } -static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterContext *ctx = inlink->dst; TInterlaceContext *tinterlace = ctx->priv; @@ -206,9 +206,10 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) avfilter_unref_buffer(tinterlace->cur); tinterlace->cur = tinterlace->next; tinterlace->next = picref; + return 0; } -static void end_frame(AVFilterLink *inlink) +static int end_frame(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; AVFilterLink *outlink = ctx->outputs[0]; @@ -220,7 +221,7 @@ static void end_frame(AVFilterLink *inlink) /* we need at least two frames */ if (!tinterlace->cur) - return; + return 0; switch (tinterlace->mode) { case MODE_MERGE: /* move the odd frame into the upper field of the new image, even into @@ -324,6 +325,8 @@ static void end_frame(AVFilterLink *inlink) ff_end_frame(outlink); tinterlace->frame++; + + return 0; } static int poll_frame(AVFilterLink *outlink) @@ -359,7 +362,7 @@ static int request_frame(AVFilterLink *outlink) 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_tinterlace = { .name = "tinterlace", diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index bdd2eff1fd..3a17d6d4ad 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -114,12 +114,16 @@ 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]; + 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); + outlink->out_buf->pts = picref->pts; if (picref->video->sample_aspect_ratio.num == 0) { @@ -129,16 +133,19 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) outlink->out_buf->video->sample_aspect_ratio.den = picref->video->sample_aspect_ratio.num; } - 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 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; @@ -189,11 +196,13 @@ 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; } -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_transpose = { .name = "transpose", diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 40e1d3ac02..13fa108ed2 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -213,24 +213,28 @@ 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 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 d7792670a6..3c06abaac9 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; @@ -64,12 +67,15 @@ 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); int i; + if (!outpicref) + return AVERROR(ENOMEM); + for (i = 0; i < 4; i ++) { int vsub = i == 1 || i == 2 ? flip->vsub : 0; @@ -79,14 +85,14 @@ 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) +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 ec096b8b7d..bf63636d06 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -156,11 +156,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 ? @@ -172,6 +172,9 @@ static void 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; } @@ -192,15 +195,19 @@ 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 void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { AVFilterContext *ctx = link->dst; YADIFContext *yadif = ctx->priv; @@ -217,46 +224,52 @@ 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); - avfilter_unref_buffer(yadif->prev); - yadif->prev = NULL; + if (!yadif->out) + return AVERROR(ENOMEM); + + avfilter_unref_bufferp(&yadif->prev); 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) - 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); + if (!yadif->out) + return AVERROR(ENOMEM); avfilter_copy_buffer_ref_props(yadif->out, yadif->cur); 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) +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) @@ -279,6 +292,9 @@ static int request_frame(AVFilterLink *link) if (ret == AVERROR_EOF && yadif->cur) { 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); @@ -323,9 +339,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) @@ -381,7 +397,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 0eed22129a..92b16b2b53 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -149,13 +149,15 @@ AVFilterBufferRef *ff_get_video_buffer(AVFilterLink *link, int perms, int w, int return ret; } -void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~0); - ff_start_frame(link->dst->outputs[0], buf_out); + if (!buf_out) + return AVERROR(ENOMEM); + return ff_start_frame(link->dst->outputs[0], buf_out); } -static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) +static int default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { AVFilterLink *outlink = NULL; @@ -163,21 +165,37 @@ static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) outlink = inlink->dst->outputs[0]; if (outlink) { + AVFilterBufferRef *buf_out; outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); + if (!outlink->out_buf) + return AVERROR(ENOMEM); + avfilter_copy_buffer_ref_props(outlink->out_buf, picref); outlink->out_buf->video->w = outlink->w; outlink->out_buf->video->h = outlink->h; - ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); + buf_out = avfilter_ref_buffer(outlink->out_buf, ~0); + if (!buf_out) + return AVERROR(ENOMEM); + + return ff_start_frame(outlink, buf_out); } + return 0; +} + +static void clear_link(AVFilterLink *link) +{ + avfilter_unref_bufferp(&link->cur_buf); + avfilter_unref_bufferp(&link->src_buf); + avfilter_unref_bufferp(&link->out_buf); } /* XXX: should we do the duplicating of the picture ref here, instead of * forcing the source filter to do it? */ -void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { - void (*start_frame)(AVFilterLink *, AVFilterBufferRef *); + int (*start_frame)(AVFilterLink *, AVFilterBufferRef *); AVFilterPad *dst = link->dstpad; - int perms = picref->perms; + int ret, perms = picref->perms; AVFilterCommand *cmd= link->dst->command_queue; int64_t pts; @@ -196,6 +214,11 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) link->dstpad->min_perms, link->dstpad->rej_perms); link->cur_buf = ff_get_video_buffer(link, dst->min_perms, link->w, link->h); + if (!link->cur_buf) { + avfilter_unref_bufferp(&picref); + return AVERROR(ENOMEM); + } + link->src_buf = picref; avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf); @@ -215,22 +238,26 @@ void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) cmd= link->dst->command_queue; } pts = link->cur_buf->pts; - start_frame(link, link->cur_buf); + ret = start_frame(link, link->cur_buf); ff_update_link_current_pts(link,link->cur_buf ? link->cur_buf->pts : pts); + if (ret < 0) + clear_link(link); + + return ret; } -void ff_null_start_frame_keep_ref(AVFilterLink *inlink, +int ff_null_start_frame_keep_ref(AVFilterLink *inlink, AVFilterBufferRef *picref) { - ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); + return ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); } -void ff_null_end_frame(AVFilterLink *link) +int ff_null_end_frame(AVFilterLink *link) { - ff_end_frame(link->dst->outputs[0]); + return ff_end_frame(link->dst->outputs[0]); } -static void default_end_frame(AVFilterLink *inlink) +static int default_end_frame(AVFilterLink *inlink) { AVFilterLink *outlink = NULL; @@ -238,37 +265,32 @@ static void default_end_frame(AVFilterLink *inlink) outlink = inlink->dst->outputs[0]; if (outlink) { - ff_end_frame(outlink); + return ff_end_frame(outlink); } + return 0; } -void ff_end_frame(AVFilterLink *link) +int ff_end_frame(AVFilterLink *link) { - void (*end_frame)(AVFilterLink *); + int (*end_frame)(AVFilterLink *); + int ret; if (!(end_frame = link->dstpad->end_frame)) end_frame = default_end_frame; - end_frame(link); + ret = end_frame(link); - /* unreference the source picture if we're feeding the destination filter - * a copied version dues to permission issues */ - if (link->src_buf) { - avfilter_unref_buffer(link->src_buf); - link->src_buf = NULL; - } - if(link->cur_buf != link->out_buf) - avfilter_unref_bufferp(&link->cur_buf); - link->cur_buf = NULL; - avfilter_unref_bufferp(&link->out_buf); + clear_link(link); + + return ret; } -void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { - ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); + return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); } -static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +static int default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { AVFilterLink *outlink = NULL; @@ -276,14 +298,15 @@ static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir outlink = inlink->dst->outputs[0]; if (outlink) - ff_draw_slice(outlink, y, h, slice_dir); + return ff_draw_slice(outlink, y, h, slice_dir); + return 0; } -void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +int ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { uint8_t *src[4], *dst[4]; - int i, j, vsub; - void (*draw_slice)(AVFilterLink *, int, int, int); + int i, j, vsub, ret; + int (*draw_slice)(AVFilterLink *, int, int, int); FF_TPRINTF_START(NULL, draw_slice); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir); @@ -317,11 +340,14 @@ void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) if (!(draw_slice = link->dstpad->draw_slice)) draw_slice = default_draw_slice; - draw_slice(link, y, h, slice_dir); + ret = draw_slice(link, y, h, slice_dir); + if (ret < 0) + clear_link(link); + return ret; } -void avfilter_default_end_frame(AVFilterLink *inlink) +int avfilter_default_end_frame(AVFilterLink *inlink) { - default_end_frame(inlink); + return default_end_frame(inlink); } diff --git a/libavfilter/video.h b/libavfilter/video.h index 28835b9bf9..e30980ea88 100644 --- a/libavfilter/video.h +++ b/libavfilter/video.h @@ -42,9 +42,9 @@ 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); -void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); -void ff_null_end_frame(AVFilterLink *link); +int ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); +int ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); +int ff_null_end_frame(AVFilterLink *link); /** * Notify the next filter of the start of a frame. @@ -54,20 +54,25 @@ 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); /** * Pass video frame along and keep an internal reference for later use. */ -void ff_null_start_frame_keep_ref(AVFilterLink *inlink, AVFilterBufferRef *picref); +int ff_null_start_frame_keep_ref(AVFilterLink *inlink, 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. @@ -83,7 +88,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 */ diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c index 82d2d32b1e..f6c0460e8a 100644 --- a/libavfilter/vsink_nullsink.c +++ b/libavfilter/vsink_nullsink.c @@ -19,12 +19,14 @@ #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) +static int end_frame(AVFilterLink *link) { + return 0; } AVFilter avfilter_vsink_nullsink = { diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index eee443ad1d..1f26a509d1 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -149,18 +149,38 @@ 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; + + if (!picref) + return AVERROR(ENOMEM); + picref->video->sample_aspect_ratio = (AVRational) {1, 1}; picref->pts = color->pts++; picref->pos = -1; - 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; + ff_fill_rectangle(&color->draw, &color->color, picref->data, picref->linesize, 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_testsrc.c b/libavfilter/vsrc_testsrc.c index 511a546007..7229d4dffc 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -134,10 +134,14 @@ 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; 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; @@ -147,9 +151,10 @@ static int request_frame(AVFilterLink *outlink) test->fill_picture_fn(outlink->src, picref); test->nb_frame++; - 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; } diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 42aa961a41..bb61042775 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -656,8 +656,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 */ diff --git a/tests/Makefile b/tests/Makefile index 9b52f07b4a..d9afb30fda 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -54,6 +54,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..cd309abc4d --- /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 = pcm -i $(SRC) -af aresample=min_comp=0.001:min_hard_comp=0.1 +fate-filter-asyncts: CMP = oneoff +fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont.pcm + +FATE_FILTER += $(FATE_ASYNCTS) +FATE_SAMPLES_AVCONV += $(FATE_ASYNCTS) + +fate-filter: $(FATE_FILTER) |