FFmpeg
audio_mix.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdint.h>
22 
23 #include "libavutil/common.h"
24 #include "libavutil/libm.h"
25 #include "libavutil/samplefmt.h"
26 #include "avresample.h"
27 #include "internal.h"
28 #include "audio_data.h"
29 #include "audio_mix.h"
30 
31 static const char * const coeff_type_names[] = { "q8", "q15", "flt" };
32 
33 struct AudioMix {
37  uint64_t in_layout;
38  uint64_t out_layout;
41 
42  int ptr_align;
45  const char *func_descr;
46  const char *func_descr_generic;
49 
58  void **matrix;
59 };
60 
63  int out_channels, int ptr_align, int samples_align,
64  const char *descr, void *mix_func)
65 {
66  if (fmt == am->fmt && coeff_type == am->coeff_type &&
67  ( in_channels == am->in_matrix_channels || in_channels == 0) &&
68  (out_channels == am->out_matrix_channels || out_channels == 0)) {
69  char chan_str[16];
70  am->mix = mix_func;
71  am->func_descr = descr;
72  am->ptr_align = ptr_align;
74  if (ptr_align == 1 && samples_align == 1) {
75  am->mix_generic = mix_func;
76  am->func_descr_generic = descr;
77  } else {
78  am->has_optimized_func = 1;
79  }
80  if (in_channels) {
81  if (out_channels)
82  snprintf(chan_str, sizeof(chan_str), "[%d to %d] ",
83  in_channels, out_channels);
84  else
85  snprintf(chan_str, sizeof(chan_str), "[%d to any] ",
86  in_channels);
87  } else if (out_channels) {
88  snprintf(chan_str, sizeof(chan_str), "[any to %d] ",
89  out_channels);
90  } else {
91  snprintf(chan_str, sizeof(chan_str), "[any to any] ");
92  }
93  av_log(am->avr, AV_LOG_DEBUG, "audio_mix: found function: [fmt=%s] "
94  "[c=%s] %s(%s)\n", av_get_sample_fmt_name(fmt),
95  coeff_type_names[coeff_type], chan_str, descr);
96  }
97 }
98 
99 #define MIX_FUNC_NAME(fmt, cfmt) mix_any_ ## fmt ##_## cfmt ##_c
100 
101 #define MIX_FUNC_GENERIC(fmt, cfmt, stype, ctype, sumtype, expr) \
102 static void MIX_FUNC_NAME(fmt, cfmt)(stype **samples, ctype **matrix, \
103  int len, int out_ch, int in_ch) \
104 { \
105  int i, in, out; \
106  stype temp[AVRESAMPLE_MAX_CHANNELS]; \
107  for (i = 0; i < len; i++) { \
108  for (out = 0; out < out_ch; out++) { \
109  sumtype sum = 0; \
110  for (in = 0; in < in_ch; in++) \
111  sum += samples[in][i] * matrix[out][in]; \
112  temp[out] = expr; \
113  } \
114  for (out = 0; out < out_ch; out++) \
115  samples[out][i] = temp[out]; \
116  } \
117 }
118 
119 MIX_FUNC_GENERIC(FLTP, FLT, float, float, float, sum)
120 MIX_FUNC_GENERIC(S16P, FLT, int16_t, float, float, av_clip_int16(lrintf(sum)))
121 MIX_FUNC_GENERIC(S16P, Q15, int16_t, int32_t, int64_t, av_clip_int16(sum >> 15))
122 MIX_FUNC_GENERIC(S16P, Q8, int16_t, int16_t, int32_t, av_clip_int16(sum >> 8))
123 
124 /* TODO: templatize the channel-specific C functions */
125 
126 static void mix_2_to_1_fltp_flt_c(float **samples, float **matrix, int len,
127  int out_ch, int in_ch)
128 {
129  float *src0 = samples[0];
130  float *src1 = samples[1];
131  float *dst = src0;
132  float m0 = matrix[0][0];
133  float m1 = matrix[0][1];
134 
135  while (len > 4) {
136  *dst++ = *src0++ * m0 + *src1++ * m1;
137  *dst++ = *src0++ * m0 + *src1++ * m1;
138  *dst++ = *src0++ * m0 + *src1++ * m1;
139  *dst++ = *src0++ * m0 + *src1++ * m1;
140  len -= 4;
141  }
142  while (len > 0) {
143  *dst++ = *src0++ * m0 + *src1++ * m1;
144  len--;
145  }
146 }
147 
148 static void mix_2_to_1_s16p_flt_c(int16_t **samples, float **matrix, int len,
149  int out_ch, int in_ch)
150 {
151  int16_t *src0 = samples[0];
152  int16_t *src1 = samples[1];
153  int16_t *dst = src0;
154  float m0 = matrix[0][0];
155  float m1 = matrix[0][1];
156 
157  while (len > 4) {
158  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
159  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
160  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
161  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
162  len -= 4;
163  }
164  while (len > 0) {
165  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
166  len--;
167  }
168 }
169 
170 static void mix_2_to_1_s16p_q8_c(int16_t **samples, int16_t **matrix, int len,
171  int out_ch, int in_ch)
172 {
173  int16_t *src0 = samples[0];
174  int16_t *src1 = samples[1];
175  int16_t *dst = src0;
176  int16_t m0 = matrix[0][0];
177  int16_t m1 = matrix[0][1];
178 
179  while (len > 4) {
180  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
181  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
182  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
183  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
184  len -= 4;
185  }
186  while (len > 0) {
187  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
188  len--;
189  }
190 }
191 
192 static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len,
193  int out_ch, int in_ch)
194 {
195  float v;
196  float *dst0 = samples[0];
197  float *dst1 = samples[1];
198  float *src = dst0;
199  float m0 = matrix[0][0];
200  float m1 = matrix[1][0];
201 
202  while (len > 4) {
203  v = *src++;
204  *dst0++ = v * m0;
205  *dst1++ = v * m1;
206  v = *src++;
207  *dst0++ = v * m0;
208  *dst1++ = v * m1;
209  v = *src++;
210  *dst0++ = v * m0;
211  *dst1++ = v * m1;
212  v = *src++;
213  *dst0++ = v * m0;
214  *dst1++ = v * m1;
215  len -= 4;
216  }
217  while (len > 0) {
218  v = *src++;
219  *dst0++ = v * m0;
220  *dst1++ = v * m1;
221  len--;
222  }
223 }
224 
225 static void mix_6_to_2_fltp_flt_c(float **samples, float **matrix, int len,
226  int out_ch, int in_ch)
227 {
228  float v0, v1;
229  float *src0 = samples[0];
230  float *src1 = samples[1];
231  float *src2 = samples[2];
232  float *src3 = samples[3];
233  float *src4 = samples[4];
234  float *src5 = samples[5];
235  float *dst0 = src0;
236  float *dst1 = src1;
237  float *m0 = matrix[0];
238  float *m1 = matrix[1];
239 
240  while (len > 0) {
241  v0 = *src0++;
242  v1 = *src1++;
243  *dst0++ = v0 * m0[0] +
244  v1 * m0[1] +
245  *src2 * m0[2] +
246  *src3 * m0[3] +
247  *src4 * m0[4] +
248  *src5 * m0[5];
249  *dst1++ = v0 * m1[0] +
250  v1 * m1[1] +
251  *src2++ * m1[2] +
252  *src3++ * m1[3] +
253  *src4++ * m1[4] +
254  *src5++ * m1[5];
255  len--;
256  }
257 }
258 
259 static void mix_2_to_6_fltp_flt_c(float **samples, float **matrix, int len,
260  int out_ch, int in_ch)
261 {
262  float v0, v1;
263  float *dst0 = samples[0];
264  float *dst1 = samples[1];
265  float *dst2 = samples[2];
266  float *dst3 = samples[3];
267  float *dst4 = samples[4];
268  float *dst5 = samples[5];
269  float *src0 = dst0;
270  float *src1 = dst1;
271 
272  while (len > 0) {
273  v0 = *src0++;
274  v1 = *src1++;
275  *dst0++ = v0 * matrix[0][0] + v1 * matrix[0][1];
276  *dst1++ = v0 * matrix[1][0] + v1 * matrix[1][1];
277  *dst2++ = v0 * matrix[2][0] + v1 * matrix[2][1];
278  *dst3++ = v0 * matrix[3][0] + v1 * matrix[3][1];
279  *dst4++ = v0 * matrix[4][0] + v1 * matrix[4][1];
280  *dst5++ = v0 * matrix[5][0] + v1 * matrix[5][1];
281  len--;
282  }
283 }
284 
286 {
287  am->func_descr = am->func_descr_generic = "n/a";
288  am->mix = am->mix_generic = NULL;
289 
290  /* no need to set a mix function when we're skipping mixing */
291  if (!am->in_matrix_channels || !am->out_matrix_channels)
292  return 0;
293 
294  /* any-to-any C versions */
295 
297  0, 0, 1, 1, "C", MIX_FUNC_NAME(FLTP, FLT));
298 
300  0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, FLT));
301 
303  0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q15));
304 
306  0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q8));
307 
308  /* channel-specific C versions */
309 
311  2, 1, 1, 1, "C", mix_2_to_1_fltp_flt_c);
312 
314  2, 1, 1, 1, "C", mix_2_to_1_s16p_flt_c);
315 
317  2, 1, 1, 1, "C", mix_2_to_1_s16p_q8_c);
318 
320  1, 2, 1, 1, "C", mix_1_to_2_fltp_flt_c);
321 
323  6, 2, 1, 1, "C", mix_6_to_2_fltp_flt_c);
324 
326  2, 6, 1, 1, "C", mix_2_to_6_fltp_flt_c);
327 
328  if (ARCH_X86)
330 
331  if (!am->mix) {
332  av_log(am->avr, AV_LOG_ERROR, "audio_mix: NO FUNCTION FOUND: [fmt=%s] "
333  "[c=%s] [%d to %d]\n", av_get_sample_fmt_name(am->fmt),
335  am->out_channels);
336  return AVERROR_PATCHWELCOME;
337  }
338  return 0;
339 }
340 
342 {
343  AudioMix *am;
344  int ret;
345 
346  am = av_mallocz(sizeof(*am));
347  if (!am)
348  return NULL;
349  am->avr = avr;
350 
353  av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
354  "mixing: %s\n",
356  goto error;
357  }
358 
359  am->fmt = avr->internal_sample_fmt;
360  am->coeff_type = avr->mix_coeff_type;
361  am->in_layout = avr->in_channel_layout;
362  am->out_layout = avr->out_channel_layout;
363  am->in_channels = avr->in_channels;
364  am->out_channels = avr->out_channels;
365 
366  /* build matrix if the user did not already set one */
367  if (avr->mix_matrix) {
368  ret = ff_audio_mix_set_matrix(am, avr->mix_matrix, avr->in_channels);
369  if (ret < 0)
370  goto error;
371  av_freep(&avr->mix_matrix);
372  } else {
373  double *matrix_dbl = av_mallocz(avr->out_channels * avr->in_channels *
374  sizeof(*matrix_dbl));
375  if (!matrix_dbl)
376  goto error;
377 
379  avr->out_channel_layout,
380  avr->center_mix_level,
381  avr->surround_mix_level,
382  avr->lfe_mix_level,
383  avr->normalize_mix_level,
384  matrix_dbl,
385  avr->in_channels,
386  avr->matrix_encoding);
387  if (ret < 0) {
388  av_free(matrix_dbl);
389  goto error;
390  }
391 
392  ret = ff_audio_mix_set_matrix(am, matrix_dbl, avr->in_channels);
393  if (ret < 0) {
394  av_log(avr, AV_LOG_ERROR, "error setting mix matrix\n");
395  av_free(matrix_dbl);
396  goto error;
397  }
398 
399  av_free(matrix_dbl);
400  }
401 
402  return am;
403 
404 error:
405  av_free(am);
406  return NULL;
407 }
408 
410 {
411  AudioMix *am;
412 
413  if (!*am_p)
414  return;
415  am = *am_p;
416 
417  if (am->matrix) {
418  av_free(am->matrix[0]);
419  am->matrix = NULL;
420  }
421  memset(am->matrix_q8, 0, sizeof(am->matrix_q8 ));
422  memset(am->matrix_q15, 0, sizeof(am->matrix_q15));
423  memset(am->matrix_flt, 0, sizeof(am->matrix_flt));
424 
425  av_freep(am_p);
426 }
427 
429 {
430  int use_generic = 1;
431  int len = src->nb_samples;
432  int i, j;
433 
434  /* determine whether to use the optimized function based on pointer and
435  samples alignment in both the input and output */
436  if (am->has_optimized_func) {
437  int aligned_len = FFALIGN(len, am->samples_align);
438  if (!(src->ptr_align % am->ptr_align) &&
439  src->samples_align >= aligned_len) {
440  len = aligned_len;
441  use_generic = 0;
442  }
443  }
444  av_log(am->avr, AV_LOG_TRACE, "audio_mix: %d samples - %d to %d channels (%s)\n",
445  src->nb_samples, am->in_channels, am->out_channels,
446  use_generic ? am->func_descr_generic : am->func_descr);
447 
448  if (am->in_matrix_channels && am->out_matrix_channels) {
449  uint8_t **data;
450  uint8_t *data0[AVRESAMPLE_MAX_CHANNELS] = { NULL };
451 
452  if (am->out_matrix_channels < am->out_channels ||
453  am->in_matrix_channels < am->in_channels) {
454  for (i = 0, j = 0; i < FFMAX(am->in_channels, am->out_channels); i++) {
455  if (am->input_skip[i] || am->output_skip[i] || am->output_zero[i])
456  continue;
457  data0[j++] = src->data[i];
458  }
459  data = data0;
460  } else {
461  data = src->data;
462  }
463 
464  if (use_generic)
465  am->mix_generic(data, am->matrix, len, am->out_matrix_channels,
466  am->in_matrix_channels);
467  else
468  am->mix(data, am->matrix, len, am->out_matrix_channels,
469  am->in_matrix_channels);
470  }
471 
472  if (am->out_matrix_channels < am->out_channels) {
473  for (i = 0; i < am->out_channels; i++)
474  if (am->output_zero[i])
475  av_samples_set_silence(&src->data[i], 0, len, 1, am->fmt);
476  }
477 
479 
480  return 0;
481 }
482 
484 {
485  int i, o, i0, o0;
486 
487  if ( am->in_channels <= 0 || am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
489  av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
490  return AVERROR(EINVAL);
491  }
492 
493 #define GET_MATRIX_CONVERT(suffix, scale) \
494  if (!am->matrix_ ## suffix[0]) { \
495  av_log(am->avr, AV_LOG_ERROR, "matrix is not set\n"); \
496  return AVERROR(EINVAL); \
497  } \
498  for (o = 0, o0 = 0; o < am->out_channels; o++) { \
499  for (i = 0, i0 = 0; i < am->in_channels; i++) { \
500  if (am->input_skip[i] || am->output_zero[o]) \
501  matrix[o * stride + i] = 0.0; \
502  else \
503  matrix[o * stride + i] = am->matrix_ ## suffix[o0][i0] * \
504  (scale); \
505  if (!am->input_skip[i]) \
506  i0++; \
507  } \
508  if (!am->output_zero[o]) \
509  o0++; \
510  }
511 
512  switch (am->coeff_type) {
514  GET_MATRIX_CONVERT(q8, 1.0 / 256.0);
515  break;
517  GET_MATRIX_CONVERT(q15, 1.0 / 32768.0);
518  break;
520  GET_MATRIX_CONVERT(flt, 1.0);
521  break;
522  default:
523  av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
524  return AVERROR(EINVAL);
525  }
526 
527  return 0;
528 }
529 
530 static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
531 {
532  int i, o;
533 
534  memset(am->output_zero, 0, sizeof(am->output_zero));
535  memset(am->input_skip, 0, sizeof(am->input_skip));
536  memset(am->output_skip, 0, sizeof(am->output_skip));
537 
538  /* exclude output channels if they can be zeroed instead of mixed */
539  for (o = 0; o < am->out_channels; o++) {
540  int zero = 1;
541 
542  /* check if the output is always silent */
543  for (i = 0; i < am->in_channels; i++) {
544  if (matrix[o * stride + i] != 0.0) {
545  zero = 0;
546  break;
547  }
548  }
549  /* check if the corresponding input channel makes a contribution to
550  any output channel */
551  if (o < am->in_channels) {
552  for (i = 0; i < am->out_channels; i++) {
553  if (matrix[i * stride + o] != 0.0) {
554  zero = 0;
555  break;
556  }
557  }
558  }
559  if (zero) {
560  am->output_zero[o] = 1;
561  am->out_matrix_channels--;
562  if (o < am->in_channels)
563  am->in_matrix_channels--;
564  }
565  }
566  if (am->out_matrix_channels == 0 || am->in_matrix_channels == 0) {
567  am->out_matrix_channels = 0;
568  am->in_matrix_channels = 0;
569  return;
570  }
571 
572  /* skip input channels that contribute fully only to the corresponding
573  output channel */
574  for (i = 0; i < FFMIN(am->in_channels, am->out_channels); i++) {
575  int skip = 1;
576 
577  for (o = 0; o < am->out_channels; o++) {
578  int i0;
579  if ((o != i && matrix[o * stride + i] != 0.0) ||
580  (o == i && matrix[o * stride + i] != 1.0)) {
581  skip = 0;
582  break;
583  }
584  /* if the input contributes fully to the output, also check that no
585  other inputs contribute to this output */
586  if (o == i) {
587  for (i0 = 0; i0 < am->in_channels; i0++) {
588  if (i0 != i && matrix[o * stride + i0] != 0.0) {
589  skip = 0;
590  break;
591  }
592  }
593  }
594  }
595  if (skip) {
596  am->input_skip[i] = 1;
597  am->in_matrix_channels--;
598  }
599  }
600  /* skip input channels that do not contribute to any output channel */
601  for (; i < am->in_channels; i++) {
602  int contrib = 0;
603 
604  for (o = 0; o < am->out_channels; o++) {
605  if (matrix[o * stride + i] != 0.0) {
606  contrib = 1;
607  break;
608  }
609  }
610  if (!contrib) {
611  am->input_skip[i] = 1;
612  am->in_matrix_channels--;
613  }
614  }
615  if (am->in_matrix_channels == 0) {
616  am->out_matrix_channels = 0;
617  return;
618  }
619 
620  /* skip output channels that only get full contribution from the
621  corresponding input channel */
622  for (o = 0; o < FFMIN(am->in_channels, am->out_channels); o++) {
623  int skip = 1;
624  int o0;
625 
626  for (i = 0; i < am->in_channels; i++) {
627  if ((o != i && matrix[o * stride + i] != 0.0) ||
628  (o == i && matrix[o * stride + i] != 1.0)) {
629  skip = 0;
630  break;
631  }
632  }
633  /* check if the corresponding input channel makes a contribution to
634  any other output channel */
635  i = o;
636  for (o0 = 0; o0 < am->out_channels; o0++) {
637  if (o0 != i && matrix[o0 * stride + i] != 0.0) {
638  skip = 0;
639  break;
640  }
641  }
642  if (skip) {
643  am->output_skip[o] = 1;
644  am->out_matrix_channels--;
645  }
646  }
647  if (am->out_matrix_channels == 0) {
648  am->in_matrix_channels = 0;
649  return;
650  }
651 }
652 
653 int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
654 {
655  int i, o, i0, o0, ret;
656  char in_layout_name[128];
657  char out_layout_name[128];
658 
659  if ( am->in_channels <= 0 || am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
661  av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
662  return AVERROR(EINVAL);
663  }
664 
665  if (am->matrix) {
666  av_free(am->matrix[0]);
667  am->matrix = NULL;
668  }
669 
672 
673  reduce_matrix(am, matrix, stride);
674 
675 #define CONVERT_MATRIX(type, expr) \
676  am->matrix_## type[0] = av_mallocz(am->out_matrix_channels * \
677  am->in_matrix_channels * \
678  sizeof(*am->matrix_## type[0])); \
679  if (!am->matrix_## type[0]) \
680  return AVERROR(ENOMEM); \
681  for (o = 0, o0 = 0; o < am->out_channels; o++) { \
682  if (am->output_zero[o] || am->output_skip[o]) \
683  continue; \
684  if (o0 > 0) \
685  am->matrix_## type[o0] = am->matrix_## type[o0 - 1] + \
686  am->in_matrix_channels; \
687  for (i = 0, i0 = 0; i < am->in_channels; i++) { \
688  double v; \
689  if (am->input_skip[i] || am->output_zero[i]) \
690  continue; \
691  v = matrix[o * stride + i]; \
692  am->matrix_## type[o0][i0] = expr; \
693  i0++; \
694  } \
695  o0++; \
696  } \
697  am->matrix = (void **)am->matrix_## type;
698 
699  if (am->in_matrix_channels && am->out_matrix_channels) {
700  switch (am->coeff_type) {
702  CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
703  break;
705  CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
706  break;
708  CONVERT_MATRIX(flt, v)
709  break;
710  default:
711  av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
712  return AVERROR(EINVAL);
713  }
714  }
715 
716  ret = mix_function_init(am);
717  if (ret < 0)
718  return ret;
719 
720  av_get_channel_layout_string(in_layout_name, sizeof(in_layout_name),
721  am->in_channels, am->in_layout);
722  av_get_channel_layout_string(out_layout_name, sizeof(out_layout_name),
723  am->out_channels, am->out_layout);
724  av_log(am->avr, AV_LOG_DEBUG, "audio_mix: %s to %s\n",
725  in_layout_name, out_layout_name);
726  av_log(am->avr, AV_LOG_DEBUG, "matrix size: %d x %d\n",
728  for (o = 0; o < am->out_channels; o++) {
729  for (i = 0; i < am->in_channels; i++) {
730  if (am->output_zero[o])
731  av_log(am->avr, AV_LOG_DEBUG, " (ZERO)");
732  else if (am->input_skip[i] || am->output_zero[i] || am->output_skip[o])
733  av_log(am->avr, AV_LOG_DEBUG, " (SKIP)");
734  else
735  av_log(am->avr, AV_LOG_DEBUG, " %0.3f ",
736  matrix[o * am->in_channels + i]);
737  }
738  av_log(am->avr, AV_LOG_DEBUG, "\n");
739  }
740 
741  return 0;
742 }
#define MIX_FUNC_NAME(fmt, cfmt)
Definition: audio_mix.c:99
float, planar
Definition: samplefmt.h:69
int in_channels
number of input channels
Definition: internal.h:77
#define NULL
Definition: coverity.c:32
AV_MIX_COEFF_TYPE_Q8
Definition: avresample.h:113
int output_skip[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:54
enum AVSampleFormat fmt
Definition: audio_mix.c:35
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
double * mix_matrix
mix matrix only used if avresample_set_matrix() is called before avresample_open() ...
Definition: internal.h:103
uint64_t out_channel_layout
output channel layout
Definition: internal.h:59
uint64_t out_layout
Definition: audio_mix.c:38
static void mix_6_to_2_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:225
enum attribute_deprecated AVMixCoeffType
Definition: avresample.h:112
int16_t * matrix_q8[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:55
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
GLfloat v0
Definition: opengl_enc.c:106
int in_channels
Definition: audio_mix.c:39
#define src
Definition: vp8dsp.c:254
int ff_audio_mix(AudioMix *am, AudioData *src)
Apply channel mixing to audio data using the current mixing matrix.
Definition: audio_mix.c:428
int in_matrix_channels
Definition: audio_mix.c:50
int nb_samples
current number of samples
Definition: audio_data.h:43
double surround_mix_level
surround mix level
Definition: internal.h:65
enum AVMixCoeffType mix_coeff_type
mixing coefficient type
Definition: internal.h:63
uint8_t
#define av_cold
Definition: attributes.h:82
int out_channels
number of output channels
Definition: internal.h:78
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
int normalize_mix_level
enable mix level normalization
Definition: internal.h:67
int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
Set the current mixing matrix.
Definition: audio_mix.c:653
static void mix_2_to_1_s16p_flt_c(int16_t **samples, float **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:148
int out_channels
Definition: audio_mix.c:40
int has_optimized_func
Definition: audio_mix.c:44
#define lrintf(x)
Definition: libm_mips.h:70
int output_zero[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:52
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
int ff_audio_data_set_channels(AudioData *a, int channels)
Definition: audio_data.c:59
enum AVMixCoeffType coeff_type
Definition: audio_mix.c:36
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition: samplefmt.c:237
double center_mix_level
center mix level
Definition: internal.h:64
static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:192
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
#define zero
Definition: regdef.h:64
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition: samplefmt.c:49
#define FFMAX(a, b)
Definition: common.h:94
static const char *const coeff_type_names[]
Definition: audio_mix.c:31
mix_func * mix_generic
Definition: audio_mix.c:48
external API header
#define FFMIN(a, b)
Definition: common.h:96
int32_t
uint64_t in_channel_layout
input channel layout
Definition: internal.h:56
const char * func_descr
Definition: audio_mix.c:45
static void error(const char *err)
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
#define src1
Definition: h264pred.c:139
void( mix_func)(uint8_t **src, void **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.h:31
mix_func * mix
Definition: audio_mix.c:47
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, int normalize, double *matrix_out, int stride, enum AVMatrixEncoding matrix_encoding)
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:39
void ff_audio_mix_init_x86(AudioMix *am)
#define AVRESAMPLE_MAX_CHANNELS
Definition: avresample.h:104
enum AVSampleFormat internal_sample_fmt
internal sample format
Definition: internal.h:62
static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
Definition: audio_mix.c:530
#define llrint(x)
Definition: libm.h:394
void ff_audio_mix_free(AudioMix **am_p)
Free an AudioMix context.
Definition: audio_mix.c:409
Replacements for frequently missing libm functions.
int32_t * matrix_q15[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:56
const char * func_descr_generic
Definition: audio_mix.c:46
float * matrix_flt[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:57
#define src0
Definition: h264pred.c:138
#define snprintf
Definition: snprintf.h:34
int out_matrix_channels
Definition: audio_mix.c:51
int input_skip[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:53
static av_cold int mix_function_init(AudioMix *am)
Definition: audio_mix.c:285
int samples_align
allocated samples alignment
Definition: audio_data.h:54
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
#define GET_MATRIX_CONVERT(suffix, scale)
common internal and external API header
int samples_align
Definition: audio_mix.c:43
enum AVMatrixEncoding matrix_encoding
matrixed stereo encoding
Definition: internal.h:97
AudioMix * ff_audio_mix_alloc(AVAudioResampleContext *avr)
Allocate and initialize an AudioMix context.
Definition: audio_mix.c:341
#define CONVERT_MATRIX(type, expr)
int ptr_align
Definition: audio_mix.c:42
#define av_free(p)
int len
static void mix_2_to_1_s16p_q8_c(int16_t **samples, int16_t **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:170
#define lrint
Definition: tablegen.h:53
static void mix_2_to_6_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:259
AV_MIX_COEFF_TYPE_FLT
32-bit 17.15 fixed-point
Definition: avresample.h:113
void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt, enum AVMixCoeffType coeff_type, int in_channels, int out_channels, int ptr_align, int samples_align, const char *descr, void *mix_func)
Set mixing function if the parameters match.
Definition: audio_mix.c:61
Filter the word “frame” indicates either a video frame or a group of audio samples
#define av_freep(p)
signed 16 bits, planar
Definition: samplefmt.h:67
int ptr_align
minimum data pointer alignment
Definition: audio_data.h:53
uint64_t in_layout
Definition: audio_mix.c:37
AV_MIX_COEFF_TYPE_Q15
16-bit 8.8 fixed-point
Definition: avresample.h:113
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
double lfe_mix_level
lfe mix level
Definition: internal.h:66
void ** matrix
Definition: audio_mix.c:58
int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
Get the current mixing matrix.
Definition: audio_mix.c:483
#define MIX_FUNC_GENERIC(fmt, cfmt, stype, ctype, sumtype, expr)
Definition: audio_mix.c:101
AVAudioResampleContext * avr
Definition: audio_mix.c:34