X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Faf_amix.c;h=bfba1504ea66fc0b803c64bbd1d2b1a171eb71a6;hb=85baef4ff1512bcc2544928bfa5f42072903a691;hp=7bb43ea53e8ddf953ca87b4d15eb16eece135331;hpb=1d9c2dc89a2302076a68b4a3ae3639abbb1a502d;p=ffmpeg diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 7bb43ea53e8..bfba1504ea6 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -28,10 +28,11 @@ * 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" @@ -176,15 +177,15 @@ typedef struct MixContext { #define A AV_OPT_FLAG_AUDIO_PARAM static const AVOption options[] = { { "inputs", "Number of inputs.", - OFFSET(nb_inputs), AV_OPT_TYPE_INT, { 2 }, 1, 32, A }, + OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 32, A }, { "duration", "How to determine the end-of-stream.", - OFFSET(duration_mode), AV_OPT_TYPE_INT, { DURATION_LONGEST }, 0, 2, A, "duration" }, - { "longest", "Duration of longest input.", 0, AV_OPT_TYPE_CONST, { DURATION_LONGEST }, INT_MIN, INT_MAX, A, "duration" }, - { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { DURATION_SHORTEST }, INT_MIN, INT_MAX, A, "duration" }, - { "first", "Duration of first input.", 0, AV_OPT_TYPE_CONST, { DURATION_FIRST }, INT_MIN, INT_MAX, A, "duration" }, + OFFSET(duration_mode), AV_OPT_TYPE_INT, { .i64 = DURATION_LONGEST }, 0, 2, A, "duration" }, + { "longest", "Duration of longest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_LONGEST }, INT_MIN, INT_MAX, A, "duration" }, + { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_SHORTEST }, INT_MIN, INT_MAX, A, "duration" }, + { "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 }, }; @@ -275,18 +276,20 @@ static int output_frame(AVFilterLink *outlink, int nb_samples) { 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) { @@ -306,13 +309,13 @@ static int output_frame(AVFilterLink *outlink, int nb_samples) } } } - 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); } /** @@ -453,7 +456,7 @@ static int request_frame(AVFilterLink *outlink) 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; @@ -472,33 +475,24 @@ static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) 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]; @@ -507,7 +501,7 @@ static int init(AVFilterContext *ctx, const char *args) 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); } @@ -517,7 +511,7 @@ static int init(AVFilterContext *ctx, const char *args) return 0; } -static void uninit(AVFilterContext *ctx) +static av_cold void uninit(AVFilterContext *ctx) { int i; MixContext *s = ctx->priv; @@ -547,19 +541,28 @@ static int query_formats(AVFilterContext *ctx) return 0; } -AVFilter avfilter_af_amix = { +static const AVFilterPad avfilter_af_amix_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_AUDIO, + .config_props = config_output, + .request_frame = request_frame + }, + { NULL } +}; + +AVFilter ff_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, };