Signed-off-by: Paul B Mahol <one...@gmail.com> --- libavfilter/avfilter.c | 96 ++++++++++++++++++++++++++++++++++++++++++ libavfilter/filters.h | 17 ++++++++ 2 files changed, 113 insertions(+)
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 93e866b79c..1dad873dfc 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -1195,6 +1195,61 @@ static int take_samples(AVFilterLink *link, unsigned min, unsigned max, return 0; } +static int peek_samples(AVFilterLink *link, unsigned peek_samples, + AVFrame **rframe) +{ + AVFrame *frame0, *frame, *buf; + unsigned nb_samples, nb_frames, i, p; + int ret; + + /* Note: this function relies on no format changes and must only be + called with enough samples. */ + av_assert1(samples_ready(link, link->min_samples)); + frame0 = frame = ff_framequeue_peek(&link->fifo, 0); + if (!link->fifo.samples_skipped && frame->nb_samples == peek_samples) { + *rframe = frame; + return 0; + } + nb_frames = 0; + nb_samples = 0; + while (1) { + if (nb_samples + frame->nb_samples >= peek_samples) + break; + nb_samples += frame->nb_samples; + nb_frames++; + if (nb_frames == ff_framequeue_queued_frames(&link->fifo)) + break; + frame = ff_framequeue_peek(&link->fifo, nb_frames); + } + + buf = ff_get_audio_buffer(link, peek_samples); + if (!buf) + return AVERROR(ENOMEM); + ret = av_frame_copy_props(buf, frame0); + if (ret < 0) { + av_frame_free(&buf); + return ret; + } + buf->pts = frame0->pts; + + p = 0; + for (i = 0; i < nb_frames; i++) { + frame = ff_framequeue_peek(&link->fifo, i); + av_samples_copy(buf->extended_data, frame->extended_data, p, 0, + frame->nb_samples, link->channels, link->format); + p += frame->nb_samples; + } + if (p < peek_samples) { + unsigned n = peek_samples - p; + frame = ff_framequeue_peek(&link->fifo, i); + av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n, + link->channels, link->format); + } + + *rframe = buf; + return 0; +} + static int ff_filter_frame_to_filter(AVFilterLink *link) { AVFrame *frame = NULL; @@ -1517,6 +1572,47 @@ int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, return 1; } +int ff_inlink_peek_samples(AVFilterLink *link, unsigned nb_samples, + AVFrame **rframe) +{ + AVFrame *frame; + int ret; + + av_assert1(nb_samples); + *rframe = NULL; + if (!ff_inlink_check_available_samples(link, nb_samples)) + return 0; + if (link->status_in) + nb_samples = FFMIN(nb_samples, ff_framequeue_queued_samples(&link->fifo)); + ret = peek_samples(link, nb_samples, &frame); + if (ret < 0) + return ret; + *rframe = frame; + return 1; +} + +void ff_inlink_skip_samples(AVFilterLink *link, unsigned skip_samples) +{ + while (skip_samples > 0) { + AVFrame *frame = ff_inlink_peek_frame(link, 0); + if (skip_samples >= frame->nb_samples) { + frame = ff_framequeue_take(&link->fifo); + skip_samples -= frame->nb_samples; + av_frame_free(&frame); + } else { + break; + } + } + + if (skip_samples) + ff_framequeue_skip_samples(&link->fifo, skip_samples, link->time_base); + + if (ff_inlink_queued_frames(link)) { + AVFrame *frame = ff_inlink_peek_frame(link, 0); + consume_update(link, frame); + } +} + AVFrame *ff_inlink_peek_frame(AVFilterLink *link, size_t idx) { return ff_framequeue_peek(&link->fifo, idx); diff --git a/libavfilter/filters.h b/libavfilter/filters.h index 1157755403..7dc0b35981 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -115,6 +115,23 @@ int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe); int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe); +/** + * Peek samples from the link's FIFO. + * + * @return >0 if a samples are available, + * 0 and set rframe to NULL if no samples are available, + * or AVERROR code + */ +int ff_inlink_peek_samples(AVFilterLink *link, unsigned nb_samples, + AVFrame **rframe); + +/** + * Skip samples from the link's FIFO. + * + * @note May trigger process_command() and/or update is_disabled. + */ +void ff_inlink_skip_samples(AVFilterLink *link, unsigned skip); + /** * Access a frame in the link fifo without consuming it. * The first frame is numbered 0; the designated frame must exist. -- 2.17.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel