diff options
author | Nicolas George <nicolas.george@normalesup.org> | 2013-03-10 13:33:18 +0100 |
---|---|---|
committer | Nicolas George <nicolas.george@normalesup.org> | 2013-03-10 13:56:17 +0100 |
commit | b0012de420f20d5731b90af1f2a3e7093f2195d9 (patch) | |
tree | 2b3fed590dfd42581082e71ccae2c597e5e5d4c3 /libavfilter/buffersrc.c | |
parent | cb2bd91413af28ca9a0202e9b92ee7c1e3d9dd2e (diff) | |
download | ffmpeg-b0012de420f20d5731b90af1f2a3e7093f2195d9.tar.gz |
lavfi/buffersrc: implement flags.
The PUSH flags is necessary for efficient scheduling;
otherwise there is no feedback when adding frames to
closed paths.
The NO_CHECK_FORMAT is a small optimization that does
not cost much to implement.
The KEEP_REF flag maps to the add/write distinction in
the fork's API.
Diffstat (limited to 'libavfilter/buffersrc.c')
-rw-r--r-- | libavfilter/buffersrc.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index 6c6689b4ca..185018dfd9 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -75,14 +75,23 @@ typedef struct { return AVERROR(EINVAL);\ } -int av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) +int av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame) { - return av_buffersrc_add_frame(ctx, frame); + return av_buffersrc_add_frame_flags(ctx, (AVFrame *)frame, + AV_BUFFERSRC_FLAG_KEEP_REF); } -int av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame) +int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame) { - AVFrame *copy; + return av_buffersrc_add_frame_flags(ctx, frame, 0); +} + +static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, + AVFrame *frame, int flags); + +int av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) +{ + AVFrame *copy = NULL; int ret = 0; int64_t layout = frame->channel_layout; @@ -91,22 +100,25 @@ int av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame) return AVERROR(EINVAL); } + if (!(flags & AV_BUFFERSRC_FLAG_KEEP_REF) || !frame) + return av_buffersrc_add_frame_internal(ctx, frame, flags); + if (!(copy = av_frame_alloc())) return AVERROR(ENOMEM); ret = av_frame_ref(copy, frame); if (ret >= 0) - ret = av_buffersrc_add_frame(ctx, copy); + ret = av_buffersrc_add_frame_internal(ctx, copy, flags); av_frame_free(©); return ret; } -int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame) +static int av_buffersrc_add_frame_internal(AVFilterContext *ctx, + AVFrame *frame, int flags) { BufferSourceContext *s = ctx->priv; AVFrame *copy; int ret; - int64_t layout; if (!frame) { s->eof = 1; @@ -114,6 +126,8 @@ int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame) } else if (s->eof) return AVERROR(EINVAL); + if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) { + switch (ctx->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height, @@ -122,17 +136,13 @@ int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame) case AVMEDIA_TYPE_AUDIO: CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout, frame->format); - - layout = frame->channel_layout; - if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) { - av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); - return AVERROR(EINVAL); - } break; default: return AVERROR(EINVAL); } + } + if (!av_fifo_space(s->fifo) && (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) + sizeof(copy))) < 0) @@ -148,6 +158,10 @@ int av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame) return ret; } + if ((flags & AV_BUFFERSRC_FLAG_PUSH)) + if ((ret = ctx->output_pads[0].request_frame(ctx->outputs[0])) < 0) + return ret; + return 0; } |