Paul B Mahol (12020-04-18): > 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 394811916d..90c73fb64b 100644 > --- a/libavfilter/avfilter.c > +++ b/libavfilter/avfilter.c > @@ -1190,6 +1190,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 = av_frame_clone(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; > +}
This is a copy-paste of take_samples() with only minimal changes. Please make more effort to share the code. > + > static int ff_filter_frame_to_filter(AVFilterLink *link) > { > AVFrame *frame = NULL; > @@ -1512,6 +1567,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 !!frame; > +} > + > +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. Regards, -- Nicolas George
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".