Signed-off-by: Shiqi Zhu <hiccup...@gmail.com> --- libavfilter/af_amix.c | 64 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 7 deletions(-)
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index bc97200926..3a74ff4772 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -44,6 +44,7 @@ #include "audio.h" #include "avfilter.h" #include "filters.h" +#include "formats.h" #define INPUT_ON 1 /**< input is active */ #define INPUT_EOF 2 /**< input has reached EOF (may still be active) */ @@ -165,7 +166,8 @@ typedef struct MixContext { char *weights_str; /**< string for custom weights for every input */ int normalize; /**< if inputs are scaled */ - int nb_channels; /**< number of channels */ + enum AVSampleFormat sample_fmt; /**< sample format */ + AVChannelLayout ch_layout; /**< channel layout */ int sample_rate; /**< sample rate */ int planar; AVAudioFifo **fifos; /**< audio fifo for each input */ @@ -197,6 +199,12 @@ static const AVOption amix_options[] = { OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, A|F|T }, { "normalize", "Scale inputs", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, A|F|T }, + { "sample_rate", "sample_rate", + OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=0}, -1, INT32_MAX, A|F }, + { "ch_layout", "ch_layout", + OFFSET(ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, 0, 0, A|F }, + { "sample_fmt", "sample_fmt", + OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64=AV_SAMPLE_FMT_NONE}, -1, INT_MAX, A|F }, { NULL } }; @@ -260,9 +268,15 @@ static int config_output(AVFilterLink *outlink) if (!s->fifos) return AVERROR(ENOMEM); - s->nb_channels = outlink->ch_layout.nb_channels; + if (s->ch_layout.nb_channels == 0) + av_channel_layout_copy(&s->ch_layout, &outlink->ch_layout); + if (av_channel_layout_compare(&s->ch_layout, &outlink->ch_layout)) { + av_log(ctx, AV_LOG_ERROR, "Output channel layouts do not match\n"); + return AVERROR(EINVAL); + } + for (i = 0; i < s->nb_inputs; i++) { - s->fifos[i] = av_audio_fifo_alloc(outlink->format, s->nb_channels, 1024); + s->fifos[i] = av_audio_fifo_alloc(outlink->format, s->ch_layout.nb_channels, 1024); if (!s->fifos[i]) return AVERROR(ENOMEM); } @@ -356,8 +370,8 @@ static int output_frame(AVFilterLink *outlink) av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data, nb_samples); - planes = s->planar ? s->nb_channels : 1; - plane_size = nb_samples * (s->planar ? 1 : s->nb_channels); + planes = s->planar ? s->ch_layout.nb_channels : 1; + plane_size = nb_samples * (s->planar ? 1 : s->ch_layout.nb_channels); plane_size = FFALIGN(plane_size, 16); if (out_buf->format == AV_SAMPLE_FMT_FLT || @@ -608,6 +622,43 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar return 0; } +static int query_formats(const AVFilterContext *ctx, + AVFilterFormatsConfig **cfg_in, + AVFilterFormatsConfig **cfg_out) +{ + const enum AVSampleFormat sample_fmts[] = { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP, + AV_SAMPLE_FMT_NONE + }; + MixContext *s = ctx->priv; + int ret; + + if (s->sample_fmt != AV_SAMPLE_FMT_NONE) { + if ((ret = ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_make_formats_list_singleton(s->sample_fmt))) < 0) + return ret; + } else { + if ((ret = ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_make_format_list(sample_fmts))) < 0) + return ret; + } + + if (s->sample_rate) { + int sample_rates[] = { s->sample_rate, -1 }; + if ((ret = ff_set_common_samplerates2(ctx, cfg_in, cfg_out, ff_make_format_list(sample_rates))) < 0) + return ret; + } else { + if ((ret = ff_set_common_samplerates2(ctx, cfg_in, cfg_out, ff_all_samplerates())) < 0) + return ret; + } + + if (s->ch_layout.nb_channels) { + const AVChannelLayout layout_list[] = { s->ch_layout, { 0 } }; + return ff_set_common_channel_layouts2(ctx, cfg_in, cfg_out, ff_make_channel_layout_list(layout_list)); + } else { + return ff_set_common_channel_layouts2(ctx, cfg_in, cfg_out, ff_all_channel_counts()); + } +} + static const AVFilterPad avfilter_af_amix_outputs[] = { { .name = "default", @@ -626,8 +677,7 @@ const AVFilter ff_af_amix = { .activate = activate, .inputs = NULL, FILTER_OUTPUTS(avfilter_af_amix_outputs), - FILTER_SAMPLEFMTS(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBLP), + FILTER_QUERY_FUNC2(query_formats), .process_command = process_command, .flags = AVFILTER_FLAG_DYNAMIC_INPUTS, }; -- 2.34.1 _______________________________________________ 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".