FFmpeg
rematrix.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
3  *
4  * This file is part of libswresample
5  *
6  * libswresample 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  * libswresample 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 libswresample; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "swresample_internal.h"
22 #include "libavutil/avassert.h"
24 #include "libavutil/mem.h"
25 
26 #define TEMPLATE_REMATRIX_FLT
27 #include "rematrix_template.c"
28 #undef TEMPLATE_REMATRIX_FLT
29 
30 #define TEMPLATE_REMATRIX_DBL
31 #include "rematrix_template.c"
32 #undef TEMPLATE_REMATRIX_DBL
33 
34 #define TEMPLATE_REMATRIX_S16
35 #include "rematrix_template.c"
36 #define TEMPLATE_CLIP
37 #include "rematrix_template.c"
38 #undef TEMPLATE_CLIP
39 #undef TEMPLATE_REMATRIX_S16
40 
41 #define TEMPLATE_REMATRIX_S32
42 #include "rematrix_template.c"
43 #undef TEMPLATE_REMATRIX_S32
44 
45 #define FRONT_LEFT 0
46 #define FRONT_RIGHT 1
47 #define FRONT_CENTER 2
48 #define LOW_FREQUENCY 3
49 #define BACK_LEFT 4
50 #define BACK_RIGHT 5
51 #define FRONT_LEFT_OF_CENTER 6
52 #define FRONT_RIGHT_OF_CENTER 7
53 #define BACK_CENTER 8
54 #define SIDE_LEFT 9
55 #define SIDE_RIGHT 10
56 #define TOP_CENTER 11
57 #define TOP_FRONT_LEFT 12
58 #define TOP_FRONT_CENTER 13
59 #define TOP_FRONT_RIGHT 14
60 #define TOP_BACK_LEFT 15
61 #define TOP_BACK_CENTER 16
62 #define TOP_BACK_RIGHT 17
63 #define NUM_NAMED_CHANNELS 18
64 
65 int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
66 {
67  int nb_in, nb_out, in, out;
68 
69  if (!s || s->in_convert || // s needs to be allocated but not initialized
70  swri_check_chlayout(s, &s->user_in_chlayout , "input") ||
71  swri_check_chlayout(s, &s->user_out_chlayout, "output")
72  )
73  return AVERROR(EINVAL);
74  memset(s->matrix, 0, sizeof(s->matrix));
75 
76  nb_in = s->user_in_chlayout.nb_channels;
77  nb_out = s->user_out_chlayout.nb_channels;
78  for (out = 0; out < nb_out; out++) {
79  for (in = 0; in < nb_in; in++)
80  s->matrix[out][in] = matrix[in];
81  matrix += stride;
82  }
83  s->rematrix_custom = 1;
84  return 0;
85 }
86 
87 static int even(int64_t layout){
88  if(!layout) return 1;
89  if(layout&(layout-1)) return 1;
90  return 0;
91 }
92 
93 static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
94 {
95  int ret = 0;
96 
98  char buf[128];
99  av_channel_layout_describe(in, buf, sizeof(buf));
100  av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf);
102  } else
104 
105  return ret;
106 }
107 
108 static int sane_layout(AVChannelLayout *ch_layout) {
109  if(ch_layout->nb_channels >= SWR_CH_MAX)
110  return 0;
111  if(ch_layout->order == AV_CHANNEL_ORDER_CUSTOM)
112  for (int i = 0; i < ch_layout->nb_channels; i++) {
113  if (ch_layout->u.map[i].id >= 64)
114  return 0;
115  }
116  else if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE)
117  return 0;
118  if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
119  return 0;
120  if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)))) // no asymmetric front
121  return 0;
122  if(!even(av_channel_layout_subset(ch_layout, (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)))) // no asymmetric side
123  return 0;
125  return 0;
127  return 0;
129  return 0;
131  return 0;
132 
133  return 1;
134 }
135 
136 static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLayout *out_ch_layout,
137  double center_mix_level, double surround_mix_level,
138  double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param,
139  ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding)
140 {
142  uint64_t unaccounted = av_channel_layout_subset(in_ch_layout, UINT64_MAX) &
143  ~av_channel_layout_subset(out_ch_layout, UINT64_MAX);
144  double maxcoef=0;
145  int i, j;
146 
147  for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){
148  if( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0
149  && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0)
150  matrix[i][i]= 1.0;
151  }
152 
153 //FIXME implement dolby surround
154 //FIXME implement full ac3
155 
156  if(unaccounted & AV_CH_FRONT_CENTER){
158  if (av_channel_layout_subset(in_ch_layout, AV_CH_LAYOUT_STEREO)) {
159  matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level;
160  matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level;
161  } else {
164  }
165  }else
166  av_assert0(0);
167  }
168  if(unaccounted & AV_CH_LAYOUT_STEREO){
173  matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2);
174  }else
175  av_assert0(0);
176  }
177 
178  if(unaccounted & AV_CH_BACK_CENTER){
179  if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
182  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
185  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
186  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
187  matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
188  if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
189  matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
190  matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
191  } else {
192  matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
193  matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
194  }
195  } else {
196  matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
197  matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
198  }
199  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
200  matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
201  }else
202  av_assert0(0);
203  }
204  if(unaccounted & AV_CH_BACK_LEFT){
208  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
212  }else{
213  matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
214  matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
215  }
216  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
217  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
218  matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
219  matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
220  matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
221  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
222  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
223  matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
224  matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
225  matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
226  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
227  } else {
228  matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level;
229  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
230  }
231  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
232  matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2;
233  matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2;
234  }else
235  av_assert0(0);
236  }
237 
238  if(unaccounted & AV_CH_SIDE_LEFT){
239  if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
240  /* if back channels do not exist in the input, just copy side
241  channels to back channels, otherwise mix side into back */
245  } else {
246  matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
247  matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
248  }
249  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) {
252  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
253  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
254  matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
255  matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
256  matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
257  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
258  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
259  matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
260  matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
261  matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
262  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
263  } else {
264  matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level;
265  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
266  }
267  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
268  matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2;
269  matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2;
270  }else
271  av_assert0(0);
272  }
273 
274  if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
275  if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
278  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
281  }else
282  av_assert0(0);
283  }
284 
285  if (unaccounted & AV_CH_TOP_FRONT_LEFT) {
290  matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2);
291  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
292  /* U+030 -> M+030 in ITU-R BS.2127-1, Table 16. */
293  matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += 1.0;
295  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
298  } else
299  av_assert0(0);
300  }
301 
302  if (unaccounted & AV_CH_TOP_BACK_LEFT) {
306  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_TOP_FRONT_LEFT) >= 0) {
307  /* IAMF v1.1.0, Section 7.3.2.1.1. */
310  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
311  matrix[BACK_LEFT ][TOP_BACK_LEFT ] += 1.0;
313  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
314  matrix[SIDE_LEFT ][TOP_BACK_LEFT ] += 1.0;
316  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
317  matrix[FRONT_LEFT ][TOP_BACK_LEFT ] += surround_mix_level;
318  matrix[FRONT_RIGHT][TOP_BACK_RIGHT] += surround_mix_level;
319  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
322  } else
323  av_assert0(0);
324  }
325 
326  /* BS.2127-1 maps U+180 to rear outputs before front outputs. */
327  if (unaccounted & AV_CH_TOP_BACK_CENTER) {
331  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
334  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
337  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
340  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0)
342  else
343  av_assert0(0);
344  }
345 
346  /* mix LFE into front left/right or center */
347  if (unaccounted & AV_CH_LOW_FREQUENCY) {
349  matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level;
350  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
351  matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
352  matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
353  } else
354  av_assert0(0);
355  }
356 
357 
358  for (i = 0; i < 64; i++) {
359  double sum=0;
360  int out_i = av_channel_layout_index_from_channel(out_ch_layout, i);
361  if (out_i < 0)
362  continue;
363  for(j=0; j<64; j++){
364  int in_i = av_channel_layout_index_from_channel(in_ch_layout, j);
365  if (in_i < 0)
366  continue;
367  if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0]))
368  matrix_param[stride*out_i + in_i] = matrix[i][j];
369  else
370  matrix_param[stride*out_i + in_i] = i == j &&
371  ( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0
372  && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0);
373  sum += fabs(matrix_param[stride*out_i + in_i]);
374  }
375  maxcoef= FFMAX(maxcoef, sum);
376  }
377  if(rematrix_volume < 0)
378  maxcoef = -rematrix_volume;
379 
380  if(maxcoef > maxval || rematrix_volume < 0){
381  maxcoef /= maxval;
382  for(i=0; i<SWR_CH_MAX; i++)
383  for(j=0; j<SWR_CH_MAX; j++){
384  matrix_param[stride*i + j] /= maxcoef;
385  }
386  }
387 }
388 
389 av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout,
390  double center_mix_level, double surround_mix_level,
391  double lfe_mix_level, double maxval,
392  double rematrix_volume, double *matrix_param,
393  ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
394 {
395  int i, j, ret;
396  AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 };
397  char buf[128];
398 
399  ret = clean_layout(&in_ch_layout, in_layout, log_context);
400  ret |= clean_layout(&out_ch_layout, out_layout, log_context);
401  if (ret < 0)
402  goto fail;
403 
406  ) {
407  av_channel_layout_uninit(&out_ch_layout);
408  out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
409  }
412  ) {
413  av_channel_layout_uninit(&in_ch_layout);
415  }
419  av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
420  av_log(log_context, AV_LOG_WARNING,
421  "Full-on remixing from 22.2 has not yet been implemented! "
422  "Processing the input as '%s'\n",
423  buf);
424  }
425 
426  if(!av_channel_layout_check(&in_ch_layout)) {
427  av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n");
428  ret = AVERROR(EINVAL);
429  goto fail;
430  }
431  if(!sane_layout(&in_ch_layout)) {
432  av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
433  av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
434  ret = AVERROR(EINVAL);
435  goto fail;
436  }
437 
438  if(!av_channel_layout_check(&out_ch_layout)) {
439  av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n");
440  ret = AVERROR(EINVAL);
441  goto fail;
442  }
443  if(!sane_layout(&out_ch_layout)) {
444  av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf));
445  av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
446  ret = AVERROR(EINVAL);
447  goto fail;
448  }
449 
450  build_matrix(&in_ch_layout, &out_ch_layout, center_mix_level,
451  surround_mix_level, lfe_mix_level, maxval, rematrix_volume,
452  matrix_param, stride, matrix_encoding);
453 
454  if(rematrix_volume > 0){
455  for(i=0; i<SWR_CH_MAX; i++)
456  for(j=0; j<SWR_CH_MAX; j++){
457  matrix_param[stride*i + j] *= rematrix_volume;
458  }
459  }
460 
461  av_log(log_context, AV_LOG_DEBUG, "Matrix coefficients:\n");
462  for (i = 0; i < out_ch_layout.nb_channels; i++){
463  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&out_ch_layout, i));
464  av_log(log_context, AV_LOG_DEBUG, "%s: ", buf);
465  for (j = 0; j < in_ch_layout.nb_channels; j++){
466  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&in_ch_layout, j));
467  av_log(log_context, AV_LOG_DEBUG, "%s:%f ", buf, matrix_param[stride*i + j]);
468  }
469  av_log(log_context, AV_LOG_DEBUG, "\n");
470  }
471 
472  ret = 0;
473 fail:
474  av_channel_layout_uninit(&in_ch_layout);
475  av_channel_layout_uninit(&out_ch_layout);
476 
477  return ret;
478 }
479 
481 {
482  double maxval;
483 
484  if (s->rematrix_maxval > 0) {
485  maxval = s->rematrix_maxval;
486  } else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
487  || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) {
488  maxval = 1.0;
489  } else
490  maxval = INT_MAX;
491 
492  memset(s->matrix, 0, sizeof(s->matrix));
493  return swr_build_matrix2(&s->in_ch_layout, &s->out_ch_layout,
494  s->clev, s->slev, s->lfe_mix_level,
495  maxval, s->rematrix_volume, (double*)s->matrix,
496  s->matrix[1] - s->matrix[0], s->matrix_encoding, s);
497 }
498 
500  int i, j;
501  int nb_in = s->used_ch_layout.nb_channels;
502  int nb_out = s->out.ch_count;
503 
504  s->mix_any_f = NULL;
505 
506  if (!s->rematrix_custom) {
507  int r = auto_matrix(s);
508  if (r)
509  return r;
510  } else {
511  char buf[128];
512  av_log(s, AV_LOG_DEBUG, "Custom matrix coefficients:\n");
513  double *matrix_param = (double*)s->matrix;
514  ptrdiff_t stride = s->matrix[1] - s->matrix[0];
515  for (i = 0; i < s->out_ch_layout.nb_channels; i++) {
516  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&s->out_ch_layout, i));
517  av_log(s, AV_LOG_DEBUG, "%s: ", buf);
518  for (j = 0; j < s->in_ch_layout.nb_channels; j++){
519  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&s->in_ch_layout, j));
520  av_log(s, AV_LOG_DEBUG, "%s:%f ", buf, matrix_param[stride*i + j]);
521  }
522  av_log(s, AV_LOG_DEBUG, "\n");
523  }
524  }
525  if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
526  int maxsum = 0;
527  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
528  if (!s->native_matrix)
529  return AVERROR(ENOMEM);
530  for (i = 0; i < nb_out; i++) {
531  double rem = 0;
532  int sum = 0;
533 
534  for (j = 0; j < nb_in; j++) {
535  double target = s->matrix[i][j] * 32768 + rem;
536  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
537  rem += target - ((int*)s->native_matrix)[i * nb_in + j];
538  sum += FFABS(((int*)s->native_matrix)[i * nb_in + j]);
539  }
540  maxsum = FFMAX(maxsum, sum);
541  }
542  s->native_one.i = 32768;
543  if (maxsum <= 32768) {
544  s->mix_1_1_f = copy_s16;
545  s->mix_2_1_f = sum2_s16;
546  s->mix_any_f = get_mix_any_func_s16(s);
547  } else {
548  s->mix_1_1_f = copy_clip_s16;
549  s->mix_2_1_f = sum2_clip_s16;
550  s->mix_any_f = get_mix_any_func_clip_s16(s);
551  }
552  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
553  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float));
554  if (!s->native_matrix)
555  return AVERROR(ENOMEM);
556  for (i = 0; i < nb_out; i++)
557  for (j = 0; j < nb_in; j++)
558  ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
559  s->native_one.f = 1.0;
560  s->mix_1_1_f = copy_float;
561  s->mix_2_1_f = sum2_float;
562  s->mix_any_f = get_mix_any_func_float(s);
563  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
564  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
565  if (!s->native_matrix)
566  return AVERROR(ENOMEM);
567  for (i = 0; i < nb_out; i++)
568  for (j = 0; j < nb_in; j++)
569  ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
570  s->native_one.d = 1.0;
571  s->mix_1_1_f = copy_double;
572  s->mix_2_1_f = sum2_double;
573  s->mix_any_f = get_mix_any_func_double(s);
574  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
575  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
576  if (!s->native_matrix)
577  return AVERROR(ENOMEM);
578  for (i = 0; i < nb_out; i++) {
579  double rem = 0;
580 
581  for (j = 0; j < nb_in; j++) {
582  double target = s->matrix[i][j] * 32768 + rem;
583  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
584  rem += target - ((int*)s->native_matrix)[i * nb_in + j];
585  }
586  }
587  s->native_one.i = 32768;
588  s->mix_1_1_f = copy_s32;
589  s->mix_2_1_f = sum2_s32;
590  s->mix_any_f = get_mix_any_func_s32(s);
591  }else
592  av_assert0(0);
593  //FIXME quantize for integeres
594  for (i = 0; i < SWR_CH_MAX; i++) {
595  int ch_in=0;
596  for (j = 0; j < SWR_CH_MAX; j++) {
597  const double coeff = s->matrix[i][j];
598  if (coeff)
599  s->matrix_ch[i][++ch_in]= j;
600  switch (s->int_sample_fmt) {
601  case AV_SAMPLE_FMT_FLTP:
602  s->matrix_flt[i][j] = coeff;
603  break;
604  case AV_SAMPLE_FMT_DBLP:
605  break;
606  default:
607  s->matrix32[i][j] = lrintf(coeff * 32768);
608  break;
609  }
610  }
611  s->matrix_ch[i][0]= ch_in;
612  }
613 
614 #if ARCH_X86 && HAVE_X86ASM
615  return swri_rematrix_init_x86(s);
616 #endif
617 
618  return 0;
619 }
620 
622  av_freep(&s->native_matrix);
623  av_freep(&s->native_simd_matrix);
624 }
625 
626 int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
627  int out_i, in_i, i, j;
628  int len1 = 0;
629  int off = 0;
630 
631  if(s->mix_any_f) {
632  s->mix_any_f(out->ch, (const uint8_t *const *)in->ch, s->native_matrix, len);
633  return 0;
634  }
635 
636  if(s->mix_2_1_simd || s->mix_1_1_simd){
637  len1= len&~15;
638  off = len1 * out->bps;
639  }
640 
641  av_assert0(s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || out->ch_count == s->out_ch_layout.nb_channels);
642  av_assert0(s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || in ->ch_count == s->in_ch_layout.nb_channels);
643 
644  for(out_i=0; out_i<out->ch_count; out_i++){
645  switch(s->matrix_ch[out_i][0]){
646  case 0:
647  if(mustcopy)
648  memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
649  break;
650  case 1:
651  in_i= s->matrix_ch[out_i][1];
652  if(s->matrix[out_i][in_i]!=1.0){
653  if(s->mix_1_1_simd && len1)
654  s->mix_1_1_simd(out->ch[out_i] , in->ch[in_i] , s->native_simd_matrix, in->ch_count*out_i + in_i, len1);
655  if(len != len1)
656  s->mix_1_1_f (out->ch[out_i]+off, in->ch[in_i]+off, s->native_matrix, in->ch_count*out_i + in_i, len-len1);
657  }else if(mustcopy){
658  memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
659  }else{
660  out->ch[out_i]= in->ch[in_i];
661  }
662  break;
663  case 2: {
664  int in_i1 = s->matrix_ch[out_i][1];
665  int in_i2 = s->matrix_ch[out_i][2];
666  if(s->mix_2_1_simd && len1)
667  s->mix_2_1_simd(out->ch[out_i] , in->ch[in_i1] , in->ch[in_i2] , s->native_simd_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1);
668  else
669  s->mix_2_1_f (out->ch[out_i] , in->ch[in_i1] , in->ch[in_i2] , s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1);
670  if(len != len1)
671  s->mix_2_1_f (out->ch[out_i]+off, in->ch[in_i1]+off, in->ch[in_i2]+off, s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len-len1);
672  break;}
673  default:
674  if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){
675  for(i=0; i<len; i++){
676  float v=0;
677  for(j=0; j<s->matrix_ch[out_i][0]; j++){
678  in_i= s->matrix_ch[out_i][1+j];
679  v+= ((float*)in->ch[in_i])[i] * s->matrix_flt[out_i][in_i];
680  }
681  ((float*)out->ch[out_i])[i]= v;
682  }
683  }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
684  for(i=0; i<len; i++){
685  double v=0;
686  for(j=0; j<s->matrix_ch[out_i][0]; j++){
687  in_i= s->matrix_ch[out_i][1+j];
688  v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
689  }
690  ((double*)out->ch[out_i])[i]= v;
691  }
692  }else{
693  for(i=0; i<len; i++){
694  int v=0;
695  for(j=0; j<s->matrix_ch[out_i][0]; j++){
696  in_i= s->matrix_ch[out_i][1+j];
697  v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
698  }
699  ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
700  }
701  }
702  }
703  }
704  return 0;
705 }
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:66
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
AV_CH_LAYOUT_7POINT1_WIDE_BACK
#define AV_CH_LAYOUT_7POINT1_WIDE_BACK
Definition: channel_layout.h:242
AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:432
r
const char * r
Definition: vf_curves.c:127
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
out
static FILE * out
Definition: movenc.c:55
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:395
NUM_NAMED_CHANNELS
#define NUM_NAMED_CHANNELS
Definition: rematrix.c:63
matrix
Definition: vc1dsp.c:43
av_cold
#define av_cold
Definition: attributes.h:119
int64_t
long long int64_t
Definition: coverity.c:34
rematrix_template.c
AVChannelLayout::map
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
Definition: channel_layout.h:370
AV_CH_TOP_FRONT_RIGHT
#define AV_CH_TOP_FRONT_RIGHT
Definition: channel_layout.h:189
av_channel_layout_channel_from_index
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
Definition: channel_layout.c:674
TOP_FRONT_RIGHT
#define TOP_FRONT_RIGHT
Definition: rematrix.c:59
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:65
swri_rematrix_init_x86
int swri_rematrix_init_x86(struct SwrContext *s)
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
sane_layout
static int sane_layout(AVChannelLayout *ch_layout)
Definition: rematrix.c:108
AV_CH_TOP_FRONT_LEFT
#define AV_CH_TOP_FRONT_LEFT
Definition: channel_layout.h:187
SQRT3_2
#define SQRT3_2
Definition: swresample_internal.h:30
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:324
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
swr_set_matrix
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
Set a customized remix matrix.
Definition: rematrix.c:65
AV_CH_TOP_BACK_LEFT
#define AV_CH_TOP_BACK_LEFT
Definition: channel_layout.h:190
AudioData
Definition: swresample_internal.h:45
AV_CH_TOP_BACK_CENTER
#define AV_CH_TOP_BACK_CENTER
Definition: channel_layout.h:191
FRONT_LEFT_OF_CENTER
#define FRONT_LEFT_OF_CENTER
Definition: rematrix.c:51
AV_CH_BACK_LEFT
#define AV_CH_BACK_LEFT
Definition: channel_layout.h:179
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:218
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
even
static int even(int64_t layout)
Definition: rematrix.c:87
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AV_MATRIX_ENCODING_DOLBY
@ AV_MATRIX_ENCODING_DOLBY
Definition: channel_layout.h:262
TOP_FRONT_LEFT
#define TOP_FRONT_LEFT
Definition: rematrix.c:57
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
av_channel_layout_describe
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
Definition: channel_layout.c:654
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
av_channel_layout_from_mask
int av_channel_layout_from_mask(AVChannelLayout *channel_layout, uint64_t mask)
Initialize a native channel layout from a bitmask indicating which channels are present.
Definition: channel_layout.c:253
AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CH_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:255
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
swri_rematrix
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy)
Definition: rematrix.c:626
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
auto_matrix
static av_cold int auto_matrix(SwrContext *s)
Definition: rematrix.c:480
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
AudioData::ch
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel
Definition: swresample_internal.h:46
FRONT_RIGHT
#define FRONT_RIGHT
Definition: rematrix.c:46
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
swr_build_matrix2
av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param, ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
Generate a channel mixing matrix.
Definition: rematrix.c:389
AVMatrixEncoding
AVMatrixEncoding
Definition: channel_layout.h:260
fail
#define fail
Definition: test.h:479
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
build_matrix
static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLayout *out_ch_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param, ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding)
Definition: rematrix.c:136
AV_CHAN_TOP_BACK_CENTER
@ AV_CHAN_TOP_BACK_CENTER
Definition: channel_layout.h:66
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:177
AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
Definition: channel_layout.h:181
TOP_BACK_RIGHT
#define TOP_BACK_RIGHT
Definition: rematrix.c:62
AV_CHANNEL_LAYOUT_22POINT2
#define AV_CHANNEL_LAYOUT_22POINT2
Definition: channel_layout.h:433
AV_CHAN_FRONT_CENTER
@ AV_CHAN_FRONT_CENTER
Definition: channel_layout.h:52
AudioData::ch_count
int ch_count
number of channels
Definition: swresample_internal.h:48
TOP_BACK_CENTER
#define TOP_BACK_CENTER
Definition: rematrix.c:61
BACK_LEFT
#define BACK_LEFT
Definition: rematrix.c:49
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:424
BACK_RIGHT
#define BACK_RIGHT
Definition: rematrix.c:50
AV_CHAN_SIDE_LEFT
@ AV_CHAN_SIDE_LEFT
Definition: channel_layout.h:59
SIDE_LEFT
#define SIDE_LEFT
Definition: rematrix.c:54
swri_rematrix_free
av_cold void swri_rematrix_free(SwrContext *s)
Definition: rematrix.c:621
swresample_internal.h
AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_BACK_RIGHT
Definition: channel_layout.h:192
AV_CHANNEL_ORDER_NATIVE
@ AV_CHANNEL_ORDER_NATIVE
The native channel order, i.e.
Definition: channel_layout.h:125
AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
Definition: channel_layout.h:182
FRONT_CENTER
#define FRONT_CENTER
Definition: rematrix.c:47
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:64
av_channel_layout_compare
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
Definition: channel_layout.c:811
layout
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 layout
Definition: filter_design.txt:18
FRONT_RIGHT_OF_CENTER
#define FRONT_RIGHT_OF_CENTER
Definition: rematrix.c:52
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:108
TOP_BACK_LEFT
#define TOP_BACK_LEFT
Definition: rematrix.c:60
av_channel_name
int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id)
Get a human readable string in an abbreviated form describing a given channel.
Definition: channel_layout.c:105
s
uint8_t s
Definition: llvidencdsp.c:39
AV_CH_BACK_CENTER
#define AV_CH_BACK_CENTER
Definition: channel_layout.h:183
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:175
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
FRONT_LEFT
#define FRONT_LEFT
Definition: rematrix.c:45
swri_check_chlayout
int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name)
Definition: swresample.c:33
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
ret
ret
Definition: filter_design.txt:187
AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_SURROUND
Definition: channel_layout.h:221
av_channel_layout_check
int av_channel_layout_check(const AVChannelLayout *channel_layout)
Check whether a channel layout is valid, i.e.
Definition: channel_layout.c:785
AV_CHAN_BACK_CENTER
@ AV_CHAN_BACK_CENTER
Definition: channel_layout.h:58
TOP_FRONT_CENTER
#define TOP_FRONT_CENTER
Definition: rematrix.c:58
M_SQRT1_2
#define M_SQRT1_2
Definition: mathematics.h:103
SWR_CH_MAX
#define SWR_CH_MAX
Definition: af_amerge.c:37
AV_CHANNEL_ORDER_CUSTOM
@ AV_CHANNEL_ORDER_CUSTOM
The channel order does not correspond to any other predefined order and is stored as an explicit map.
Definition: channel_layout.h:132
channel_layout.h
av_channel_layout_subset
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
Definition: channel_layout.c:867
AV_CHAN_TOP_BACK_LEFT
@ AV_CHAN_TOP_BACK_LEFT
Definition: channel_layout.h:65
av_channel_layout_index_from_channel
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
Definition: channel_layout.c:715
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition: channel_layout.c:443
av_get_packed_sample_fmt
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition: samplefmt.c:77
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:67
AV_CHAN_BACK_LEFT
@ AV_CHAN_BACK_LEFT
Definition: channel_layout.h:54
swri_rematrix_init
av_cold int swri_rematrix_init(SwrContext *s)
Definition: rematrix.c:499
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:176
av_channel_layout_copy
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
Definition: channel_layout.c:450
AV_CHAN_TOP_FRONT_CENTER
@ AV_CHAN_TOP_FRONT_CENTER
Definition: channel_layout.h:63
mem.h
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
LOW_FREQUENCY
#define LOW_FREQUENCY
Definition: rematrix.c:48
BACK_CENTER
#define BACK_CENTER
Definition: rematrix.c:53
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AV_CHAN_TOP_FRONT_LEFT
@ AV_CHAN_TOP_FRONT_LEFT
Definition: channel_layout.h:62
SIDE_RIGHT
#define SIDE_RIGHT
Definition: rematrix.c:55
coeff
static const double coeff[2][5]
Definition: vf_owdenoise.c:80
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_CH_BACK_RIGHT
#define AV_CH_BACK_RIGHT
Definition: channel_layout.h:180
AV_CHAN_FRONT_LEFT
@ AV_CHAN_FRONT_LEFT
Definition: channel_layout.h:50
stride
#define stride
Definition: h264pred_template.c:536
AVChannelLayout::u
union AVChannelLayout::@530 u
Details about which channels are present in this layout.
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:60
AVChannelCustom::id
enum AVChannel id
Definition: channel_layout.h:284
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:184
AV_MATRIX_ENCODING_DPLII
@ AV_MATRIX_ENCODING_DPLII
Definition: channel_layout.h:263
clean_layout
static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
Definition: rematrix.c:93