X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_select.c;h=d47876bbbae729589665ad0c61fb982d2a155bbf;hb=6c0107822d3ed7588fa857c3ed1ee886b4ba62e9;hp=9d2217102c14f01a30970be9d5f3e479355f68aa;hpb=56ae5926f739bd26a5aa4add98604b7cd3c2d6ca;p=ffmpeg diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index 9d2217102c1..d47876bbbae 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -26,6 +26,7 @@ #include "libavutil/eval.h" #include "libavutil/fifo.h" #include "libavcodec/dsputil.h" +#include "libavutil/internal.h" #include "avfilter.h" #include "formats.h" #include "internal.h" @@ -269,12 +270,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,31 +285,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; - AVFilterBufferRef *picref = inlink->cur_buf; 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]); } - avfilter_unref_buffer(picref); + return 0; } static int request_frame(AVFilterLink *outlink) @@ -319,12 +326,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) { @@ -404,17 +413,18 @@ AVFilter avfilter_vf_select = { .priv_size = sizeof(SelectContext), - .inputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .get_video_buffer = ff_null_get_video_buffer, - .config_props = config_input, - .start_frame = start_frame, - .draw_slice = draw_slice, - .end_frame = end_frame }, - { .name = NULL }}, - .outputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .poll_frame = poll_frame, - .request_frame = request_frame, }, - { .name = NULL}}, + .inputs = (const AVFilterPad[]) {{ .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .get_video_buffer = ff_null_get_video_buffer, + .min_perms = AV_PERM_PRESERVE, + .config_props = config_input, + .start_frame = start_frame, + .draw_slice = draw_slice, + .end_frame = end_frame }, + { .name = NULL }}, + .outputs = (const AVFilterPad[]) {{ .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .poll_frame = poll_frame, + .request_frame = request_frame, }, + { .name = NULL}}, };