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 
62  enum AVMixCoeffType coeff_type, int in_channels,
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;
73  am->samples_align = samples_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) {
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)
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 
483 int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
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 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:30
AVAudioResampleContext::mix_matrix
double * mix_matrix
mix matrix only used if avresample_set_matrix() is called before avresample_open()
Definition: internal.h:103
AudioMix::matrix_q8
int16_t * matrix_q8[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:55
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
stride
int stride
Definition: mace.c:144
AVERROR
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
mix_2_to_1_s16p_q8_c
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
libm.h
AVAudioResampleContext::lfe_mix_level
double lfe_mix_level
lfe mix level
Definition: internal.h:66
mix_2_to_6_fltp_flt_c
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
AudioMix::ptr_align
int ptr_align
Definition: audio_mix.c:42
AudioMix::coeff_type
enum AVMixCoeffType coeff_type
Definition: audio_mix.c:36
ff_audio_data_set_channels
int ff_audio_data_set_channels(AudioData *a, int channels)
Definition: audio_data.c:59
AVRESAMPLE_MAX_CHANNELS
#define AVRESAMPLE_MAX_CHANNELS
Definition: avresample.h:104
AV_MIX_COEFF_TYPE_Q15
AV_MIX_COEFF_TYPE_Q15
16-bit 8.8 fixed-point
Definition: avresample.h:114
av_get_channel_layout_string
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.
Definition: channel_layout.c:217
AVAudioResampleContext::out_channels
int out_channels
number of output channels
Definition: internal.h:78
mix_2_to_1_s16p_flt_c
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
data
const char data[16]
Definition: mxf.c:142
AVAudioResampleContext::matrix_encoding
enum AVMatrixEncoding matrix_encoding
matrixed stereo encoding
Definition: internal.h:97
mix_6_to_2_fltp_flt_c
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
AudioMix::matrix_q15
int32_t * matrix_q15[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:56
AudioMix::in_layout
uint64_t in_layout
Definition: audio_mix.c:37
avresample.h
ff_audio_mix_set_matrix
int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
Set the current mixing matrix.
Definition: audio_mix.c:653
AV_MIX_COEFF_TYPE_FLT
AV_MIX_COEFF_TYPE_FLT
32-bit 17.15 fixed-point
Definition: avresample.h:115
AV_MIX_COEFF_TYPE_Q8
AV_MIX_COEFF_TYPE_Q8
Definition: avresample.h:113
AudioMix::output_skip
int output_skip[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:54
AudioData
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
AudioMix::out_channels
int out_channels
Definition: audio_mix.c:40
AVAudioResampleContext
Definition: internal.h:53
v0
#define v0
Definition: regdef.h:26
coeff_type_names
static const char *const coeff_type_names[]
Definition: audio_mix.c:31
samplefmt.h
MIX_FUNC_NAME
#define MIX_FUNC_NAME(fmt, cfmt)
Definition: audio_mix.c:99
AVMixCoeffType
enum attribute_deprecated AVMixCoeffType
Definition: avresample.h:112
mix_1_to_2_fltp_flt_c
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
ff_audio_mix
int ff_audio_mix(AudioMix *am, AudioData *src)
Apply channel mixing to audio data using the current mixing matrix.
Definition: audio_mix.c:428
avresample_build_matrix
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)
Definition: audio_mix_matrix.c:87
lrint
#define lrint
Definition: tablegen.h:53
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:220
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
av_cold
#define av_cold
Definition: attributes.h:90
AudioMix
Definition: audio_mix.c:33
AudioMix::func_descr
const char * func_descr
Definition: audio_mix.c:45
AudioMix::in_channels
int in_channels
Definition: audio_mix.c:39
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
AudioMix::fmt
enum AVSampleFormat fmt
Definition: audio_mix.c:35
AudioMix::in_matrix_channels
int in_matrix_channels
Definition: audio_mix.c:50
av_get_sample_fmt_name
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
mix_func
void() mix_func(uint8_t **src, void **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.h:31
int32_t
int32_t
Definition: audio_convert.c:194
AudioMix::has_optimized_func
int has_optimized_func
Definition: audio_mix.c:44
av_clip_int16
#define av_clip_int16
Definition: common.h:137
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
AudioMix::matrix_flt
float * matrix_flt[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:57
src
#define src
Definition: vp8dsp.c:255
internal.h
AudioMix::output_zero
int output_zero[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:52
AVAudioResampleContext::surround_mix_level
double surround_mix_level
surround mix level
Definition: internal.h:65
AudioMix::mix_generic
mix_func * mix_generic
Definition: audio_mix.c:48
ff_audio_mix_init_x86
void ff_audio_mix_init_x86(AudioMix *am)
Definition: audio_mix_init.c:174
AudioMix::out_matrix_channels
int out_matrix_channels
Definition: audio_mix.c:51
audio_data.h
AudioMix::input_skip
int input_skip[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:53
AudioMix::out_layout
uint64_t out_layout
Definition: audio_mix.c:38
av_clipl_int32
#define av_clipl_int32
Definition: common.h:140
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
AudioMix::mix
mix_func * mix
Definition: audio_mix.c:47
mix_function_init
static av_cold int mix_function_init(AudioMix *am)
Definition: audio_mix.c:285
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:67
src0
#define src0
Definition: h264pred.c:139
src1
#define src1
Definition: h264pred.c:140
i
int i
Definition: input.c:407
AVAudioResampleContext::in_channel_layout
uint64_t in_channel_layout
input channel layout
Definition: internal.h:56
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
AVAudioResampleContext::in_channels
int in_channels
number of input channels
Definition: internal.h:77
AVAudioResampleContext::center_mix_level
double center_mix_level
center mix level
Definition: internal.h:64
ff_audio_mix_free
void ff_audio_mix_free(AudioMix **am_p)
Free an AudioMix context.
Definition: audio_mix.c:409
common.h
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
uint8_t
uint8_t
Definition: audio_convert.c:194
ff_audio_mix_alloc
AudioMix * ff_audio_mix_alloc(AVAudioResampleContext *avr)
Allocate and initialize an AudioMix context.
Definition: audio_mix.c:341
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
len
int len
Definition: vorbis_enc_data.h:452
AudioMix::func_descr_generic
const char * func_descr_generic
Definition: audio_mix.c:46
av_samples_set_silence
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
ff_audio_mix_set_func
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
ret
ret
Definition: filter_design.txt:187
reduce_matrix
static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
Definition: audio_mix.c:530
AVAudioResampleContext::internal_sample_fmt
enum AVSampleFormat internal_sample_fmt
internal sample format
Definition: internal.h:62
GET_MATRIX_CONVERT
#define GET_MATRIX_CONVERT(suffix, scale)
MIX_FUNC_GENERIC
#define MIX_FUNC_GENERIC(fmt, cfmt, stype, ctype, sumtype, expr)
Definition: audio_mix.c:101
CONVERT_MATRIX
#define CONVERT_MATRIX(type, expr)
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
ff_audio_mix_get_matrix
int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
Get the current mixing matrix.
Definition: audio_mix.c:483
AudioMix::avr
AVAudioResampleContext * avr
Definition: audio_mix.c:34
zero
#define zero
Definition: regdef.h:64
llrint
#define llrint(x)
Definition: libm.h:394
AVAudioResampleContext::mix_coeff_type
enum AVMixCoeffType mix_coeff_type
mixing coefficient type
Definition: internal.h:63
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AudioMix::matrix
void ** matrix
Definition: audio_mix.c:58
AVAudioResampleContext::normalize_mix_level
int normalize_mix_level
enable mix level normalization
Definition: internal.h:67
snprintf
#define snprintf
Definition: snprintf.h:34
audio_mix.h
AudioMix::samples_align
int samples_align
Definition: audio_mix.c:43
AVAudioResampleContext::out_channel_layout
uint64_t out_channel_layout
output channel layout
Definition: internal.h:59