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
41
46
47 #define INPUT_OFF 0 /**< input has reached EOF */
48 #define INPUT_ON 1 /**< input is active */
49 #define INPUT_INACTIVE 2 /**< input is on, but is currently inactive */
50
51 #define DURATION_LONGEST 0
52 #define DURATION_SHORTEST 1
53 #define DURATION_FIRST 2
54
55
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 */
76
78 {
79 if (frame_list) {
80 while (frame_list->
list) {
84 }
88 }
89 }
90
92 {
93 if (!frame_list->
list)
94 return 0;
96 }
97
99 {
100 if (!frame_list->
list)
103 }
104
106 {
109 } else {
110 int samples = nb_samples;
111 while (samples > 0) {
117 if (!frame_list->
list)
122 } else {
124 info->
pts += samples;
126 samples = 0;
127 }
128 }
129 }
130 }
131
133 {
135 if (!info)
140
141 if (!frame_list->
list) {
142 frame_list->
list = info;
143 frame_list->
end = info;
144 } else {
147 frame_list->
end = info;
148 }
151
152 return 0;
153 }
154
155
157 const AVClass *
class;
/**< class for AVOptions */
159
164
171 float scale_norm;
/**< normalization factor for all inputs */
172 int64_t
next_pts;
/**< calculated pts for next output frame */
175
176 #define OFFSET(x) offsetof(MixContext, x)
177 #define A AV_OPT_FLAG_AUDIO_PARAM
178 #define F AV_OPT_FLAG_FILTERING_PARAM
180 { "inputs", "Number of inputs.",
182 { "duration", "How to determine the end-of-stream.",
187 { "dropout_transition", "Transition time, in seconds, for volume "
188 "renormalization when an input stream ends.",
191 };
192
194
195 /**
196 * Update the scaling factors to apply to each input during mixing.
197 *
198 * This balances the full volume range between active inputs and handles
199 * volume transitions when EOF is encountered on an input but mixing continues
200 * with the remaining inputs.
201 */
203 {
204 int i;
205
209 }
210
214 else
216 }
217 }
218
220 {
223 int i;
225
230
234
238
244 }
245
251
257
259
261 "inputs:%d fmt:%s srate:%d cl:%s\n", s->
nb_inputs,
263
264 return 0;
265 }
266
267 /**
268 * Read samples from the input FIFOs, mix, and write to the output link.
269 */
271 {
275 int i;
276
278
280 if (!out_buf)
282
284 if (!in_buf) {
287 }
288
291 int planes, plane_size, p;
292
294 nb_samples);
295
298 plane_size =
FFALIGN(plane_size, 16);
299
300 for (p = 0; p < planes; p++) {
304 }
305 }
306 }
308
312
314 }
315
316 /**
317 * Returns the smallest number of samples available in the input FIFOs other
318 * than that of the first input.
319 */
321 {
322 int i;
324
326
328 int nb_samples;
330 continue;
332 available_samples =
FFMIN(available_samples, nb_samples);
333 }
334 if (available_samples == INT_MAX)
335 return 0;
337 }
338
339 /**
340 * Requests a frame, if needed, from each input link other than the first.
341 */
343 {
346
348
350 ret = 0;
352 continue;
358 continue;
359 }
360 } else if (ret < 0)
362 }
363 return 0;
364 }
365
366 /**
367 * Calculates the number of active inputs and determines EOF based on the
368 * duration option.
369 *
370 * @return 0 if mixing should continue, or AVERROR_EOF if mixing should stop.
371 */
373 {
374 int i;
375 int active_inputs = 0;
379
380 if (!active_inputs ||
384 return 0;
385 }
386
388 {
393
395 if (ret < 0)
397
400 if (ret < 0)
402
404 if (ret < 0)
406
408 if (!available_samples)
410
412 }
413
420 else
422 } else if (ret < 0)
424 }
426
428
431 if (ret < 0)
433
435 if (ret < 0)
437 }
438
441 if (!available_samples)
443 available_samples =
FFMIN(available_samples, wanted_samples);
444 } else {
445 available_samples = wanted_samples;
446 }
447
450
452 }
453
455 {
460
462 if (ctx->
inputs[i] == inlink)
463 break;
467 goto fail;
468 }
469
470 if (i == 0) {
474 if (ret < 0)
475 goto fail;
476 }
477
480
481 fail:
483
485 }
486
488 {
490 int i;
491
495
496 snprintf(name,
sizeof(name),
"input%d", i);
502
504 }
505
509
510 return 0;
511 }
512
514 {
515 int i;
517
522 }
528
531 }
532
534 {
537
539
540 if (!layouts)
542
548 return 0;
549 }
550
552 {
557 },
559 };
560
565 .priv_class = &amix_class,
570 .
outputs = avfilter_af_amix_outputs,
572 };