[FFmpeg-devel] [PATCH] lavfi: add concat filter.
Stefano Sabatini
stefasab at gmail.com
Sun Jul 22 10:12:56 CEST 2012
On date Sunday 2012-07-22 01:03:15 +0200, Nicolas George encoded:
>
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
> Changelog | 1 +
> doc/filters.texi | 75 ++++++++
> libavfilter/Makefile | 1 +
> libavfilter/allfilters.c | 1 +
> libavfilter/avf_concat.c | 436 ++++++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 514 insertions(+)
> create mode 100644 libavfilter/avf_concat.c
>
[...]
> version 0.11:
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 4a6c092..2b245c9 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -3988,6 +3988,81 @@ tools.
>
> Below is a description of the currently available transmedia filters.
>
> + at section concat
> +
> +Concatenate audio and video streams, joining them together one after the
> +other.
> +
> +The filter works on segments of synchronized video and audio streams. All
> +segments must have the same number of streams of each type, and that will
> +also be the number of streams at output.
> +
> +The filter accepts the following named parameters:
> + at table @option
> +
> + at item n
> +Set the number of segments. Default is 2.
> +
> + at item v
> +Set the number of output video streams, that is also the number of video
> +streams in each segment. Default is 1.
> +
> + at item a
> +Set the number of output audio streams, that is also the number of video
> +streams in each segment. Default is 0.
> +
> + at end table
> +
> +The filter has @var{v}+ at var{a} outputs: first @var{v} video outputs, then
> + at var{a} audio outputs.
> +
> +There are @var{s}×(@var{v}+ at var{a}) inputs: first the inputs for the first
^
-> @var{n}×(@var{v}+ at var{a})
[...]
> --- a/libavfilter/allfilters.c
> +++ b/libavfilter/allfilters.c
> @@ -134,6 +134,7 @@ void avfilter_register_all(void)
> REGISTER_FILTER (NULLSINK, nullsink, vsink);
>
> /* transmedia filters */
Note: transmedia -> multimedia, here and in the docs
> + REGISTER_FILTER (CONCAT, concat, avf);
> REGISTER_FILTER (SHOWWAVES, showwaves, avf);
>
> /* those filters are part of public or internal API => registered
> diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c
> new file mode 100644
> index 0000000..d77fb86
> --- /dev/null
> +++ b/libavfilter/avf_concat.c
[...]
> +static void send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no)
> +{
> + ConcatContext *cat = ctx->priv;
> + AVFilterLink *outlink = ctx->outputs[out_no];
> + int64_t base_pts = cat->in[in_no].pts;
> + int64_t nb_samples, sent = 0;
> + int frame_size;
> + AVRational rate_tb = { 1, ctx->inputs[in_no]->sample_rate };
> + AVFilterBufferRef *buf;
> + int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);
> +
> + if (!rate_tb.den)
> + return;
> + nb_samples = av_rescale_q(cat->delta_ts - base_pts,
> + outlink->time_base, rate_tb);
> + frame_size = FFMAX(9600, rate_tb.den / 5); /* arbitrary */
Conceptually frame size != number of samples
thus I suggest to rename frame_size -> frame_nb_samples
> + while (nb_samples) {
> + frame_size = FFMIN(frame_size, nb_samples);
> + buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, frame_size);
> + if (!buf)
> + return;
> + av_samples_set_silence(buf->extended_data, 0, frame_size,
> + nb_channels, outlink->format);
> + buf->pts = base_pts + av_rescale_q(sent, rate_tb, outlink->time_base);
> + ff_filter_samples(outlink, buf);
> + sent += frame_size;
> + nb_samples -= frame_size;
> + }
> +}
> +
[...]
Looks good to me otherwise, it's up to you to decide if applying it
immediately or after the corner case is fixed.
Ah and forgot to say, great work! :)
--
FFmpeg = Foolish Faithful Mastodontic Purposeless EniGma
More information about the ffmpeg-devel
mailing list