LCOV - code coverage report
Current view: top level - libavfilter - af_amix.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 212 263 80.6 %
Date: 2017-12-14 19:11:59 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Audio Mix Filter
       3             :  * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * Audio Mix Filter
      25             :  *
      26             :  * Mixes audio from multiple sources into a single output. The channel layout,
      27             :  * sample rate, and sample format will be the same for all inputs and the
      28             :  * output.
      29             :  */
      30             : 
      31             : #include "libavutil/attributes.h"
      32             : #include "libavutil/audio_fifo.h"
      33             : #include "libavutil/avassert.h"
      34             : #include "libavutil/avstring.h"
      35             : #include "libavutil/channel_layout.h"
      36             : #include "libavutil/common.h"
      37             : #include "libavutil/float_dsp.h"
      38             : #include "libavutil/mathematics.h"
      39             : #include "libavutil/opt.h"
      40             : #include "libavutil/samplefmt.h"
      41             : 
      42             : #include "audio.h"
      43             : #include "avfilter.h"
      44             : #include "filters.h"
      45             : #include "formats.h"
      46             : #include "internal.h"
      47             : 
      48             : #define INPUT_ON       1    /**< input is active */
      49             : #define INPUT_EOF      2    /**< input has reached EOF (may still be active) */
      50             : 
      51             : #define DURATION_LONGEST  0
      52             : #define DURATION_SHORTEST 1
      53             : #define DURATION_FIRST    2
      54             : 
      55             : 
      56             : typedef struct FrameInfo {
      57             :     int nb_samples;
      58             :     int64_t pts;
      59             :     struct FrameInfo *next;
      60             : } FrameInfo;
      61             : 
      62             : /**
      63             :  * Linked list used to store timestamps and frame sizes of all frames in the
      64             :  * FIFO for the first input.
      65             :  *
      66             :  * This is needed to keep timestamps synchronized for the case where multiple
      67             :  * input frames are pushed to the filter for processing before a frame is
      68             :  * requested by the output link.
      69             :  */
      70             : typedef struct FrameList {
      71             :     int nb_frames;
      72             :     int nb_samples;
      73             :     FrameInfo *list;
      74             :     FrameInfo *end;
      75             : } FrameList;
      76             : 
      77         612 : static void frame_list_clear(FrameList *frame_list)
      78             : {
      79         612 :     if (frame_list) {
      80        1823 :         while (frame_list->list) {
      81         605 :             FrameInfo *info = frame_list->list;
      82         605 :             frame_list->list = info->next;
      83         605 :             av_free(info);
      84             :         }
      85         609 :         frame_list->nb_frames  = 0;
      86         609 :         frame_list->nb_samples = 0;
      87         609 :         frame_list->end        = NULL;
      88             :     }
      89         612 : }
      90             : 
      91        2046 : static int frame_list_next_frame_size(FrameList *frame_list)
      92             : {
      93        2046 :     if (!frame_list->list)
      94           1 :         return 0;
      95        2045 :     return frame_list->list->nb_samples;
      96             : }
      97             : 
      98         609 : static int64_t frame_list_next_pts(FrameList *frame_list)
      99             : {
     100         609 :     if (!frame_list->list)
     101           1 :         return AV_NOPTS_VALUE;
     102         608 :     return frame_list->list->pts;
     103             : }
     104             : 
     105         609 : static void frame_list_remove_samples(FrameList *frame_list, int nb_samples)
     106             : {
     107         609 :     if (nb_samples >= frame_list->nb_samples) {
     108         606 :         frame_list_clear(frame_list);
     109             :     } else {
     110           3 :         int samples = nb_samples;
     111           9 :         while (samples > 0) {
     112           3 :             FrameInfo *info = frame_list->list;
     113           3 :             av_assert0(info);
     114           3 :             if (info->nb_samples <= samples) {
     115           0 :                 samples -= info->nb_samples;
     116           0 :                 frame_list->list = info->next;
     117           0 :                 if (!frame_list->list)
     118           0 :                     frame_list->end = NULL;
     119           0 :                 frame_list->nb_frames--;
     120           0 :                 frame_list->nb_samples -= info->nb_samples;
     121           0 :                 av_free(info);
     122             :             } else {
     123           3 :                 info->nb_samples       -= samples;
     124           3 :                 info->pts              += samples;
     125           3 :                 frame_list->nb_samples -= samples;
     126           3 :                 samples = 0;
     127             :             }
     128             :         }
     129             :     }
     130         609 : }
     131             : 
     132         605 : static int frame_list_add_frame(FrameList *frame_list, int nb_samples, int64_t pts)
     133             : {
     134         605 :     FrameInfo *info = av_malloc(sizeof(*info));
     135         605 :     if (!info)
     136           0 :         return AVERROR(ENOMEM);
     137         605 :     info->nb_samples = nb_samples;
     138         605 :     info->pts        = pts;
     139         605 :     info->next       = NULL;
     140             : 
     141         605 :     if (!frame_list->list) {
     142         605 :         frame_list->list = info;
     143         605 :         frame_list->end  = info;
     144             :     } else {
     145           0 :         av_assert0(frame_list->end);
     146           0 :         frame_list->end->next = info;
     147           0 :         frame_list->end       = info;
     148             :     }
     149         605 :     frame_list->nb_frames++;
     150         605 :     frame_list->nb_samples += nb_samples;
     151             : 
     152         605 :     return 0;
     153             : }
     154             : 
     155             : /* FIXME: use directly links fifo */
     156             : 
     157             : typedef struct MixContext {
     158             :     const AVClass *class;       /**< class for AVOptions */
     159             :     AVFloatDSPContext *fdsp;
     160             : 
     161             :     int nb_inputs;              /**< number of inputs */
     162             :     int active_inputs;          /**< number of input currently active */
     163             :     int duration_mode;          /**< mode for determining duration */
     164             :     float dropout_transition;   /**< transition time when an input drops out */
     165             : 
     166             :     int nb_channels;            /**< number of channels */
     167             :     int sample_rate;            /**< sample rate */
     168             :     int planar;
     169             :     AVAudioFifo **fifos;        /**< audio fifo for each input */
     170             :     uint8_t *input_state;       /**< current state of each input */
     171             :     float *input_scale;         /**< mixing scale factor for each input */
     172             :     float scale_norm;           /**< normalization factor for all inputs */
     173             :     int64_t next_pts;           /**< calculated pts for next output frame */
     174             :     FrameList *frame_list;      /**< list of frame info for the first input */
     175             : } MixContext;
     176             : 
     177             : #define OFFSET(x) offsetof(MixContext, x)
     178             : #define A AV_OPT_FLAG_AUDIO_PARAM
     179             : #define F AV_OPT_FLAG_FILTERING_PARAM
     180             : static const AVOption amix_options[] = {
     181             :     { "inputs", "Number of inputs.",
     182             :             OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 1024, A|F },
     183             :     { "duration", "How to determine the end-of-stream.",
     184             :             OFFSET(duration_mode), AV_OPT_TYPE_INT, { .i64 = DURATION_LONGEST }, 0,  2, A|F, "duration" },
     185             :         { "longest",  "Duration of longest input.",  0, AV_OPT_TYPE_CONST, { .i64 = DURATION_LONGEST  }, 0, 0, A|F, "duration" },
     186             :         { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_SHORTEST }, 0, 0, A|F, "duration" },
     187             :         { "first",    "Duration of first input.",    0, AV_OPT_TYPE_CONST, { .i64 = DURATION_FIRST    }, 0, 0, A|F, "duration" },
     188             :     { "dropout_transition", "Transition time, in seconds, for volume "
     189             :                             "renormalization when an input stream ends.",
     190             :             OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A|F },
     191             :     { NULL }
     192             : };
     193             : 
     194             : AVFILTER_DEFINE_CLASS(amix);
     195             : 
     196             : /**
     197             :  * Update the scaling factors to apply to each input during mixing.
     198             :  *
     199             :  * This balances the full volume range between active inputs and handles
     200             :  * volume transitions when EOF is encountered on an input but mixing continues
     201             :  * with the remaining inputs.
     202             :  */
     203         612 : static void calculate_scales(MixContext *s, int nb_samples)
     204             : {
     205             :     int i;
     206             : 
     207         612 :     if (s->scale_norm > s->active_inputs) {
     208         131 :         s->scale_norm -= nb_samples / (s->dropout_transition * s->sample_rate);
     209         131 :         s->scale_norm = FFMAX(s->scale_norm, s->active_inputs);
     210             :     }
     211             : 
     212        2098 :     for (i = 0; i < s->nb_inputs; i++) {
     213        1486 :         if (s->input_state[i] & INPUT_ON)
     214        1095 :             s->input_scale[i] = 1.0f / s->scale_norm;
     215             :         else
     216         391 :             s->input_scale[i] = 0.0f;
     217             :     }
     218         612 : }
     219             : 
     220           3 : static int config_output(AVFilterLink *outlink)
     221             : {
     222           3 :     AVFilterContext *ctx = outlink->src;
     223           3 :     MixContext *s      = ctx->priv;
     224             :     int i;
     225             :     char buf[64];
     226             : 
     227           3 :     s->planar          = av_sample_fmt_is_planar(outlink->format);
     228           3 :     s->sample_rate     = outlink->sample_rate;
     229           3 :     outlink->time_base = (AVRational){ 1, outlink->sample_rate };
     230           3 :     s->next_pts        = AV_NOPTS_VALUE;
     231             : 
     232           3 :     s->frame_list = av_mallocz(sizeof(*s->frame_list));
     233           3 :     if (!s->frame_list)
     234           0 :         return AVERROR(ENOMEM);
     235             : 
     236           3 :     s->fifos = av_mallocz_array(s->nb_inputs, sizeof(*s->fifos));
     237           3 :     if (!s->fifos)
     238           0 :         return AVERROR(ENOMEM);
     239             : 
     240           3 :     s->nb_channels = outlink->channels;
     241          10 :     for (i = 0; i < s->nb_inputs; i++) {
     242           7 :         s->fifos[i] = av_audio_fifo_alloc(outlink->format, s->nb_channels, 1024);
     243           7 :         if (!s->fifos[i])
     244           0 :             return AVERROR(ENOMEM);
     245             :     }
     246             : 
     247           3 :     s->input_state = av_malloc(s->nb_inputs);
     248           3 :     if (!s->input_state)
     249           0 :         return AVERROR(ENOMEM);
     250           3 :     memset(s->input_state, INPUT_ON, s->nb_inputs);
     251           3 :     s->active_inputs = s->nb_inputs;
     252             : 
     253           3 :     s->input_scale = av_mallocz_array(s->nb_inputs, sizeof(*s->input_scale));
     254           3 :     if (!s->input_scale)
     255           0 :         return AVERROR(ENOMEM);
     256           3 :     s->scale_norm = s->active_inputs;
     257           3 :     calculate_scales(s, 0);
     258             : 
     259           3 :     av_get_channel_layout_string(buf, sizeof(buf), -1, outlink->channel_layout);
     260             : 
     261           6 :     av_log(ctx, AV_LOG_VERBOSE,
     262             :            "inputs:%d fmt:%s srate:%d cl:%s\n", s->nb_inputs,
     263           3 :            av_get_sample_fmt_name(outlink->format), outlink->sample_rate, buf);
     264             : 
     265           3 :     return 0;
     266             : }
     267             : 
     268             : /**
     269             :  * Read samples from the input FIFOs, mix, and write to the output link.
     270             :  */
     271        1564 : static int output_frame(AVFilterLink *outlink)
     272             : {
     273        1564 :     AVFilterContext *ctx = outlink->src;
     274        1564 :     MixContext      *s = ctx->priv;
     275             :     AVFrame *out_buf, *in_buf;
     276             :     int nb_samples, ns, i;
     277             : 
     278        1564 :     if (s->input_state[0] & INPUT_ON) {
     279             :         /* first input live: use the corresponding frame size */
     280        1564 :         nb_samples = frame_list_next_frame_size(s->frame_list);
     281        2609 :         for (i = 1; i < s->nb_inputs; i++) {
     282        2000 :             if (s->input_state[i] & INPUT_ON) {
     283        1609 :                 ns = av_audio_fifo_size(s->fifos[i]);
     284        1609 :                 if (ns < nb_samples) {
     285         958 :                     if (!(s->input_state[i] & INPUT_EOF))
     286             :                         /* unclosed input with not enough samples */
     287         955 :                         return 0;
     288             :                     /* closed input to drain */
     289           3 :                     nb_samples = ns;
     290             :                 }
     291             :             }
     292             :         }
     293             :     } else {
     294             :         /* first input closed: use the available samples */
     295           0 :         nb_samples = INT_MAX;
     296           0 :         for (i = 1; i < s->nb_inputs; i++) {
     297           0 :             if (s->input_state[i] & INPUT_ON) {
     298           0 :                 ns = av_audio_fifo_size(s->fifos[i]);
     299           0 :                 nb_samples = FFMIN(nb_samples, ns);
     300             :             }
     301             :         }
     302           0 :         if (nb_samples == INT_MAX) {
     303           0 :             ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts);
     304           0 :             return 0;
     305             :         }
     306             :     }
     307             : 
     308         609 :     s->next_pts = frame_list_next_pts(s->frame_list);
     309         609 :     frame_list_remove_samples(s->frame_list, nb_samples);
     310             : 
     311         609 :     calculate_scales(s, nb_samples);
     312             : 
     313         609 :     if (nb_samples == 0)
     314           1 :         return 0;
     315             : 
     316         608 :     out_buf = ff_get_audio_buffer(outlink, nb_samples);
     317         608 :     if (!out_buf)
     318           0 :         return AVERROR(ENOMEM);
     319             : 
     320         608 :     in_buf = ff_get_audio_buffer(outlink, nb_samples);
     321         608 :     if (!in_buf) {
     322           0 :         av_frame_free(&out_buf);
     323           0 :         return AVERROR(ENOMEM);
     324             :     }
     325             : 
     326        2085 :     for (i = 0; i < s->nb_inputs; i++) {
     327        1477 :         if (s->input_state[i] & INPUT_ON) {
     328             :             int planes, plane_size, p;
     329             : 
     330        1086 :             av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data,
     331             :                                nb_samples);
     332             : 
     333        1086 :             planes     = s->planar ? s->nb_channels : 1;
     334        1086 :             plane_size = nb_samples * (s->planar ? 1 : s->nb_channels);
     335        1086 :             plane_size = FFALIGN(plane_size, 16);
     336             : 
     337        2172 :             if (out_buf->format == AV_SAMPLE_FMT_FLT ||
     338           0 :                 out_buf->format == AV_SAMPLE_FMT_FLTP) {
     339        2172 :                 for (p = 0; p < planes; p++) {
     340        3258 :                     s->fdsp->vector_fmac_scalar((float *)out_buf->extended_data[p],
     341        1086 :                                                 (float *) in_buf->extended_data[p],
     342        1086 :                                                 s->input_scale[i], plane_size);
     343             :                 }
     344             :             } else {
     345           0 :                 for (p = 0; p < planes; p++) {
     346           0 :                     s->fdsp->vector_dmac_scalar((double *)out_buf->extended_data[p],
     347           0 :                                                 (double *) in_buf->extended_data[p],
     348           0 :                                                 s->input_scale[i], plane_size);
     349             :                 }
     350             :             }
     351             :         }
     352             :     }
     353         608 :     av_frame_free(&in_buf);
     354             : 
     355         608 :     out_buf->pts = s->next_pts;
     356         608 :     if (s->next_pts != AV_NOPTS_VALUE)
     357         608 :         s->next_pts += nb_samples;
     358             : 
     359         608 :     return ff_filter_frame(outlink, out_buf);
     360             : }
     361             : 
     362             : /**
     363             :  * Requests a frame, if needed, from each input link other than the first.
     364             :  */
     365         482 : static int request_samples(AVFilterContext *ctx, int min_samples)
     366             : {
     367         482 :     MixContext *s = ctx->priv;
     368             :     int i;
     369             : 
     370         482 :     av_assert0(s->nb_inputs > 1);
     371             : 
     372        1228 :     for (i = 1; i < s->nb_inputs; i++) {
     373        1400 :         if (!(s->input_state[i] & INPUT_ON) ||
     374         654 :              (s->input_state[i] & INPUT_EOF))
     375          95 :             continue;
     376         651 :         if (av_audio_fifo_size(s->fifos[i]) >= min_samples)
     377          89 :             continue;
     378         562 :         ff_inlink_request_frame(ctx->inputs[i]);
     379             :     }
     380         482 :     return output_frame(ctx->outputs[0]);
     381             : }
     382             : 
     383             : /**
     384             :  * Calculates the number of active inputs and determines EOF based on the
     385             :  * duration option.
     386             :  *
     387             :  * @return 0 if mixing should continue, or AVERROR_EOF if mixing should stop.
     388             :  */
     389        1700 : static int calc_active_inputs(MixContext *s)
     390             : {
     391             :     int i;
     392        1700 :     int active_inputs = 0;
     393        5884 :     for (i = 0; i < s->nb_inputs; i++)
     394        4184 :         active_inputs += !!(s->input_state[i] & INPUT_ON);
     395        1700 :     s->active_inputs = active_inputs;
     396             : 
     397        3396 :     if (!active_inputs ||
     398        3653 :         (s->duration_mode == DURATION_FIRST && !(s->input_state[0] & INPUT_ON)) ||
     399        1693 :         (s->duration_mode == DURATION_SHORTEST && active_inputs != s->nb_inputs))
     400           7 :         return AVERROR_EOF;
     401        1693 :     return 0;
     402             : }
     403             : 
     404        1700 : static int activate(AVFilterContext *ctx)
     405             : {
     406        1700 :     AVFilterLink *outlink = ctx->outputs[0];
     407        1700 :     MixContext *s = ctx->priv;
     408        1700 :     AVFrame *buf = NULL;
     409             :     int i, ret;
     410             : 
     411        5884 :     for (i = 0; i < s->nb_inputs; i++) {
     412        4184 :         AVFilterLink *inlink = ctx->inputs[i];
     413             : 
     414        4184 :         if ((ret = ff_inlink_consume_frame(ctx->inputs[i], &buf)) > 0) {
     415        1082 :             if (i == 0) {
     416         605 :                 int64_t pts = av_rescale_q(buf->pts, inlink->time_base,
     417             :                                            outlink->time_base);
     418         605 :                 ret = frame_list_add_frame(s->frame_list, buf->nb_samples, pts);
     419         605 :                 if (ret < 0) {
     420           0 :                     av_frame_free(&buf);
     421           0 :                     return ret;
     422             :                 }
     423             :             }
     424             : 
     425        1082 :             ret = av_audio_fifo_write(s->fifos[i], (void **)buf->extended_data,
     426        1082 :                                       buf->nb_samples);
     427        1082 :             if (ret < 0) {
     428           0 :                 av_frame_free(&buf);
     429           0 :                 return ret;
     430             :             }
     431             : 
     432        1082 :             av_frame_free(&buf);
     433             : 
     434        1082 :             ret = output_frame(outlink);
     435        1082 :             if (ret < 0)
     436           0 :                 return ret;
     437             :         }
     438             :     }
     439             : 
     440        5884 :     for (i = 0; i < s->nb_inputs; i++) {
     441             :         int64_t pts;
     442             :         int status;
     443             : 
     444        4184 :         if (ff_inlink_acknowledge_status(ctx->inputs[i], &status, &pts)) {
     445         885 :             if (status == AVERROR_EOF) {
     446         885 :                 if (i == 0) {
     447           7 :                     s->input_state[i] = 0;
     448           7 :                     if (s->nb_inputs == 1) {
     449           0 :                         ff_outlink_set_status(outlink, status, pts);
     450           0 :                         return 0;
     451             :                     }
     452             :                 } else {
     453         878 :                     s->input_state[i] |= INPUT_EOF;
     454         878 :                     if (av_audio_fifo_size(s->fifos[i]) == 0) {
     455         874 :                         s->input_state[i] = 0;
     456             :                     }
     457             :                 }
     458             :             }
     459             :         }
     460             :     }
     461             : 
     462        1700 :     if (calc_active_inputs(s)) {
     463           7 :         ff_outlink_set_status(outlink, AVERROR_EOF, s->next_pts);
     464           7 :         return 0;
     465             :     }
     466             : 
     467        1693 :     if (ff_outlink_frame_wanted(outlink)) {
     468             :         int wanted_samples;
     469             : 
     470        1087 :         if (!(s->input_state[0] & INPUT_ON))
     471           0 :             return request_samples(ctx, 1);
     472             : 
     473        1087 :         if (s->frame_list->nb_frames == 0) {
     474         605 :             ff_inlink_request_frame(ctx->inputs[0]);
     475         605 :             return 0;
     476             :         }
     477         482 :         av_assert0(s->frame_list->nb_frames > 0);
     478             : 
     479         482 :         wanted_samples = frame_list_next_frame_size(s->frame_list);
     480             : 
     481         482 :         return request_samples(ctx, wanted_samples);
     482             :     }
     483             : 
     484         606 :     return 0;
     485             : }
     486             : 
     487           6 : static av_cold int init(AVFilterContext *ctx)
     488             : {
     489           6 :     MixContext *s = ctx->priv;
     490             :     int i, ret;
     491             : 
     492          40 :     for (i = 0; i < s->nb_inputs; i++) {
     493          14 :         AVFilterPad pad = { 0 };
     494             : 
     495          14 :         pad.type           = AVMEDIA_TYPE_AUDIO;
     496          14 :         pad.name           = av_asprintf("input%d", i);
     497          14 :         if (!pad.name)
     498           0 :             return AVERROR(ENOMEM);
     499             : 
     500          14 :         if ((ret = ff_insert_inpad(ctx, i, &pad)) < 0) {
     501           0 :             av_freep(&pad.name);
     502           0 :             return ret;
     503             :         }
     504             :     }
     505             : 
     506           6 :     s->fdsp = avpriv_float_dsp_alloc(0);
     507           6 :     if (!s->fdsp)
     508           0 :         return AVERROR(ENOMEM);
     509             : 
     510           6 :     return 0;
     511             : }
     512             : 
     513           6 : static av_cold void uninit(AVFilterContext *ctx)
     514             : {
     515             :     int i;
     516           6 :     MixContext *s = ctx->priv;
     517             : 
     518           6 :     if (s->fifos) {
     519          10 :         for (i = 0; i < s->nb_inputs; i++)
     520           7 :             av_audio_fifo_free(s->fifos[i]);
     521           3 :         av_freep(&s->fifos);
     522             :     }
     523           6 :     frame_list_clear(s->frame_list);
     524           6 :     av_freep(&s->frame_list);
     525           6 :     av_freep(&s->input_state);
     526           6 :     av_freep(&s->input_scale);
     527           6 :     av_freep(&s->fdsp);
     528             : 
     529          20 :     for (i = 0; i < ctx->nb_inputs; i++)
     530          14 :         av_freep(&ctx->input_pads[i].name);
     531           6 : }
     532             : 
     533           3 : static int query_formats(AVFilterContext *ctx)
     534             : {
     535           3 :     AVFilterFormats *formats = NULL;
     536             :     AVFilterChannelLayouts *layouts;
     537             :     int ret;
     538             : 
     539           3 :     layouts = ff_all_channel_counts();
     540           3 :     if (!layouts) {
     541           0 :         ret = AVERROR(ENOMEM);
     542           0 :         goto fail;
     543             :     }
     544             : 
     545           3 :     if ((ret = ff_add_format(&formats, AV_SAMPLE_FMT_FLT ))          < 0 ||
     546           3 :         (ret = ff_add_format(&formats, AV_SAMPLE_FMT_FLTP))          < 0 ||
     547           3 :         (ret = ff_add_format(&formats, AV_SAMPLE_FMT_DBL ))          < 0 ||
     548           3 :         (ret = ff_add_format(&formats, AV_SAMPLE_FMT_DBLP))          < 0 ||
     549           6 :         (ret = ff_set_common_formats        (ctx, formats))          < 0 ||
     550           6 :         (ret = ff_set_common_channel_layouts(ctx, layouts))          < 0 ||
     551           3 :         (ret = ff_set_common_samplerates(ctx, ff_all_samplerates())) < 0)
     552             :         goto fail;
     553           3 :     return 0;
     554           0 : fail:
     555           0 :     if (layouts)
     556           0 :         av_freep(&layouts->channel_layouts);
     557           0 :     av_freep(&layouts);
     558           0 :     return ret;
     559             : }
     560             : 
     561             : static const AVFilterPad avfilter_af_amix_outputs[] = {
     562             :     {
     563             :         .name          = "default",
     564             :         .type          = AVMEDIA_TYPE_AUDIO,
     565             :         .config_props  = config_output,
     566             :     },
     567             :     { NULL }
     568             : };
     569             : 
     570             : AVFilter ff_af_amix = {
     571             :     .name           = "amix",
     572             :     .description    = NULL_IF_CONFIG_SMALL("Audio mixing."),
     573             :     .priv_size      = sizeof(MixContext),
     574             :     .priv_class     = &amix_class,
     575             :     .init           = init,
     576             :     .uninit         = uninit,
     577             :     .activate       = activate,
     578             :     .query_formats  = query_formats,
     579             :     .inputs         = NULL,
     580             :     .outputs        = avfilter_af_amix_outputs,
     581             :     .flags          = AVFILTER_FLAG_DYNAMIC_INPUTS,
     582             : };

Generated by: LCOV version 1.13