* output.
*/
-#include "libavutil/audioconvert.h"
+#include "libavutil/attributes.h"
#include "libavutil/audio_fifo.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
+#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/float_dsp.h"
#include "libavutil/mathematics.h"
{ "first", "Duration of first input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_FIRST }, INT_MIN, INT_MAX, A, "duration" },
{ "dropout_transition", "Transition time, in seconds, for volume "
"renormalization when an input stream ends.",
- OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { 2.0 }, 0, INT_MAX, A },
+ OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A },
{ NULL },
};
{
AVFilterContext *ctx = outlink->src;
MixContext *s = ctx->priv;
- AVFilterBufferRef *out_buf, *in_buf;
+ AVFrame *out_buf, *in_buf;
int i;
calculate_scales(s, nb_samples);
- out_buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
+ out_buf = ff_get_audio_buffer(outlink, nb_samples);
if (!out_buf)
return AVERROR(ENOMEM);
- in_buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
- if (!in_buf)
+ in_buf = ff_get_audio_buffer(outlink, nb_samples);
+ if (!in_buf) {
+ av_frame_free(&out_buf);
return AVERROR(ENOMEM);
+ }
for (i = 0; i < s->nb_inputs; i++) {
if (s->input_state[i] == INPUT_ON) {
}
}
}
- avfilter_unref_buffer(in_buf);
+ av_frame_free(&in_buf);
out_buf->pts = s->next_pts;
if (s->next_pts != AV_NOPTS_VALUE)
s->next_pts += nb_samples;
- return ff_filter_samples(outlink, out_buf);
+ return ff_filter_frame(outlink, out_buf);
}
/**
return output_frame(outlink, available_samples);
}
-static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
{
AVFilterContext *ctx = inlink->dst;
MixContext *s = ctx->priv;
if (i == 0) {
int64_t pts = av_rescale_q(buf->pts, inlink->time_base,
outlink->time_base);
- ret = frame_list_add_frame(s->frame_list, buf->audio->nb_samples, pts);
+ ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts);
if (ret < 0)
goto fail;
}
ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
- buf->audio->nb_samples);
+ buf->nb_samples);
fail:
- avfilter_unref_buffer(buf);
+ av_frame_free(&buf);
return ret;
}
-static int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx)
{
MixContext *s = ctx->priv;
- int i, ret;
-
- s->class = &amix_class;
- av_opt_set_defaults(s);
-
- if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
- av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
- return ret;
- }
- av_opt_free(s);
+ int i;
for (i = 0; i < s->nb_inputs; i++) {
char name[32];
snprintf(name, sizeof(name), "input%d", i);
pad.type = AVMEDIA_TYPE_AUDIO;
pad.name = av_strdup(name);
- pad.filter_samples = filter_samples;
+ pad.filter_frame = filter_frame;
ff_insert_inpad(ctx, i, &pad);
}
return 0;
}
-static void uninit(AVFilterContext *ctx)
+static av_cold void uninit(AVFilterContext *ctx)
{
int i;
MixContext *s = ctx->priv;
return 0;
}
+static const AVFilterPad avfilter_af_amix_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .config_props = config_output,
+ .request_frame = request_frame
+ },
+ { NULL }
+};
+
AVFilter avfilter_af_amix = {
.name = "amix",
.description = NULL_IF_CONFIG_SMALL("Audio mixing."),
.priv_size = sizeof(MixContext),
+ .priv_class = &amix_class,
.init = init,
.uninit = uninit,
.query_formats = query_formats,
- .inputs = (const AVFilterPad[]) {{ .name = NULL}},
- .outputs = (const AVFilterPad[]) {{ .name = "default",
- .type = AVMEDIA_TYPE_AUDIO,
- .config_props = config_output,
- .request_frame = request_frame },
- { .name = NULL}},
+ .inputs = NULL,
+ .outputs = avfilter_af_amix_outputs,
+
+ .flags = AVFILTER_FLAG_DYNAMIC_INPUTS,
};