[FFmpeg-devel] [PATCH] libavfilter/af_amix: fixed amix format when graph load
Shiqi Zhu
hiccupzhu at gmail.com
Mon Dec 9 03:28:36 EET 2024
Signed-off-by: Shiqi Zhu <hiccupzhu at 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
More information about the ffmpeg-devel
mailing list