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  return AVERROR(EINVAL);
71  memset(s->matrix, 0, sizeof(s->matrix));
72  memset(s->matrix_flt, 0, sizeof(s->matrix_flt));
73 
74  nb_in = s->user_in_chlayout.nb_channels;
75  nb_out = s->user_out_chlayout.nb_channels;
76  for (out = 0; out < nb_out; out++) {
77  for (in = 0; in < nb_in; in++)
78  s->matrix_flt[out][in] = s->matrix[out][in] = matrix[in];
79  matrix += stride;
80  }
81  s->rematrix_custom = 1;
82  return 0;
83 }
84 
85 static int even(int64_t layout){
86  if(!layout) return 1;
87  if(layout&(layout-1)) return 1;
88  return 0;
89 }
90 
91 static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
92 {
93  int ret = 0;
94 
96  char buf[128];
97  av_channel_layout_describe(in, buf, sizeof(buf));
98  av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf);
100  } else
102 
103  return ret;
104 }
105 
106 static int sane_layout(AVChannelLayout *ch_layout) {
107  if(ch_layout->nb_channels >= SWR_CH_MAX)
108  return 0;
109  if(ch_layout->order == AV_CHANNEL_ORDER_CUSTOM)
110  for (int i = 0; i < ch_layout->nb_channels; i++) {
111  if (ch_layout->u.map[i].id >= 64)
112  return 0;
113  }
114  else if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE)
115  return 0;
116  if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
117  return 0;
118  if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)))) // no asymetric front
119  return 0;
120  if(!even(av_channel_layout_subset(ch_layout, (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)))) // no asymetric side
121  return 0;
123  return 0;
125  return 0;
127  return 0;
128 
129  return 1;
130 }
131 
132 static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLayout *out_ch_layout,
133  double center_mix_level, double surround_mix_level,
134  double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param,
135  ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding)
136 {
138  uint64_t unaccounted = av_channel_layout_subset(in_ch_layout, UINT64_MAX) &
139  ~av_channel_layout_subset(out_ch_layout, UINT64_MAX);
140  double maxcoef=0;
141  int i, j;
142 
143  for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){
144  if( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0
145  && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0)
146  matrix[i][i]= 1.0;
147  }
148 
149 //FIXME implement dolby surround
150 //FIXME implement full ac3
151 
152  if(unaccounted & AV_CH_FRONT_CENTER){
154  if (av_channel_layout_subset(in_ch_layout, AV_CH_LAYOUT_STEREO)) {
155  matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level;
156  matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level;
157  } else {
160  }
161  }else
162  av_assert0(0);
163  }
164  if(unaccounted & AV_CH_LAYOUT_STEREO){
169  matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2);
170  }else
171  av_assert0(0);
172  }
173 
174  if(unaccounted & AV_CH_BACK_CENTER){
175  if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
178  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
181  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
182  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
183  matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
184  if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
185  matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
186  matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
187  } else {
188  matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
189  matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
190  }
191  } else {
192  matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
193  matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
194  }
195  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
196  matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
197  }else
198  av_assert0(0);
199  }
200  if(unaccounted & AV_CH_BACK_LEFT){
204  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
208  }else{
209  matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
210  matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
211  }
212  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
213  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
214  matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
215  matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
216  matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
217  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
218  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
219  matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
220  matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
221  matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
222  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
223  } else {
224  matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level;
225  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
226  }
227  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
228  matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2;
229  matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2;
230  }else
231  av_assert0(0);
232  }
233 
234  if(unaccounted & AV_CH_SIDE_LEFT){
235  if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
236  /* if back channels do not exist in the input, just copy side
237  channels to back channels, otherwise mix side into back */
241  } else {
242  matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
243  matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
244  }
245  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) {
248  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
249  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
250  matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
251  matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
252  matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
253  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
254  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
255  matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
256  matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
257  matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
258  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
259  } else {
260  matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level;
261  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
262  }
263  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
264  matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2;
265  matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2;
266  }else
267  av_assert0(0);
268  }
269 
270  if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
271  if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
274  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
277  }else
278  av_assert0(0);
279  }
280 
281  if (unaccounted & AV_CH_TOP_FRONT_LEFT) {
286  matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2);
287  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
291  } else {
292  matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += 1.0;
294  }
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  /* mix LFE into front left/right or center */
303  if (unaccounted & AV_CH_LOW_FREQUENCY) {
305  matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level;
306  } else if (av_channel_layout_index_from_channel(out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
307  matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
308  matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
309  } else
310  av_assert0(0);
311  }
312 
313 
314  for (i = 0; i < 64; i++) {
315  double sum=0;
316  int out_i = av_channel_layout_index_from_channel(out_ch_layout, i);
317  if (out_i < 0)
318  continue;
319  for(j=0; j<64; j++){
320  int in_i = av_channel_layout_index_from_channel(in_ch_layout, j);
321  if (in_i < 0)
322  continue;
323  if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0]))
324  matrix_param[stride*out_i + in_i] = matrix[i][j];
325  else
326  matrix_param[stride*out_i + in_i] = i == j &&
327  ( av_channel_layout_index_from_channel(in_ch_layout, i) >= 0
328  && av_channel_layout_index_from_channel(out_ch_layout, i) >= 0);
329  sum += fabs(matrix_param[stride*out_i + in_i]);
330  }
331  maxcoef= FFMAX(maxcoef, sum);
332  }
333  if(rematrix_volume < 0)
334  maxcoef = -rematrix_volume;
335 
336  if(maxcoef > maxval || rematrix_volume < 0){
337  maxcoef /= maxval;
338  for(i=0; i<SWR_CH_MAX; i++)
339  for(j=0; j<SWR_CH_MAX; j++){
340  matrix_param[stride*i + j] /= maxcoef;
341  }
342  }
343 }
344 
345 av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout,
346  double center_mix_level, double surround_mix_level,
347  double lfe_mix_level, double maxval,
348  double rematrix_volume, double *matrix_param,
349  ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
350 {
351  int i, j, ret;
352  AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 };
353  char buf[128];
354 
355  ret = clean_layout(&in_ch_layout, in_layout, log_context);
356  ret |= clean_layout(&out_ch_layout, out_layout, log_context);
357  if (ret < 0)
358  goto fail;
359 
362  ) {
363  av_channel_layout_uninit(&out_ch_layout);
364  out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
365  }
368  ) {
369  av_channel_layout_uninit(&in_ch_layout);
371  }
375  av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
376  av_log(log_context, AV_LOG_WARNING,
377  "Full-on remixing from 22.2 has not yet been implemented! "
378  "Processing the input as '%s'\n",
379  buf);
380  }
381 
382  if(!av_channel_layout_check(&in_ch_layout)) {
383  av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n");
384  ret = AVERROR(EINVAL);
385  goto fail;
386  }
387  if(!sane_layout(&in_ch_layout)) {
388  av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
389  av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
390  ret = AVERROR(EINVAL);
391  goto fail;
392  }
393 
394  if(!av_channel_layout_check(&out_ch_layout)) {
395  av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n");
396  ret = AVERROR(EINVAL);
397  goto fail;
398  }
399  if(!sane_layout(&out_ch_layout)) {
400  av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf));
401  av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
402  ret = AVERROR(EINVAL);
403  goto fail;
404  }
405 
406  build_matrix(&in_ch_layout, &out_ch_layout, center_mix_level,
407  surround_mix_level, lfe_mix_level, maxval, rematrix_volume,
408  matrix_param, stride, matrix_encoding);
409 
410  if(rematrix_volume > 0){
411  for(i=0; i<SWR_CH_MAX; i++)
412  for(j=0; j<SWR_CH_MAX; j++){
413  matrix_param[stride*i + j] *= rematrix_volume;
414  }
415  }
416 
417  av_log(log_context, AV_LOG_DEBUG, "Matrix coefficients:\n");
418  for (i = 0; i < out_ch_layout.nb_channels; i++){
419  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&out_ch_layout, i));
420  av_log(log_context, AV_LOG_DEBUG, "%s: ", buf);
421  for (j = 0; j < in_ch_layout.nb_channels; j++){
422  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&in_ch_layout, j));
423  av_log(log_context, AV_LOG_DEBUG, "%s:%f ", buf, matrix_param[stride*i + j]);
424  }
425  av_log(log_context, AV_LOG_DEBUG, "\n");
426  }
427 
428  ret = 0;
429 fail:
430  av_channel_layout_uninit(&in_ch_layout);
431  av_channel_layout_uninit(&out_ch_layout);
432 
433  return ret;
434 }
435 
437 {
438  double maxval;
439  int ret;
440 
441  if (s->rematrix_maxval > 0) {
442  maxval = s->rematrix_maxval;
443  } else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
444  || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) {
445  maxval = 1.0;
446  } else
447  maxval = INT_MAX;
448 
449  memset(s->matrix, 0, sizeof(s->matrix));
450  ret = swr_build_matrix2(&s->in_ch_layout, &s->out_ch_layout,
451  s->clev, s->slev, s->lfe_mix_level,
452  maxval, s->rematrix_volume, (double*)s->matrix,
453  s->matrix[1] - s->matrix[0], s->matrix_encoding, s);
454 
455  if (ret >= 0 && s->int_sample_fmt == AV_SAMPLE_FMT_FLTP) {
456  int i, j;
457  for (i = 0; i < FF_ARRAY_ELEMS(s->matrix[0]); i++)
458  for (j = 0; j < FF_ARRAY_ELEMS(s->matrix[0]); j++)
459  s->matrix_flt[i][j] = s->matrix[i][j];
460  }
461 
462  return ret;
463 }
464 
466  int i, j;
467  int nb_in = s->used_ch_layout.nb_channels;
468  int nb_out = s->out.ch_count;
469 
470  s->mix_any_f = NULL;
471 
472  if (!s->rematrix_custom) {
473  int r = auto_matrix(s);
474  if (r)
475  return r;
476  }
477  if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
478  int maxsum = 0;
479  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
480  s->native_one = av_mallocz(sizeof(int));
481  if (!s->native_matrix || !s->native_one)
482  return AVERROR(ENOMEM);
483  for (i = 0; i < nb_out; i++) {
484  double rem = 0;
485  int sum = 0;
486 
487  for (j = 0; j < nb_in; j++) {
488  double target = s->matrix[i][j] * 32768 + rem;
489  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
490  rem += target - ((int*)s->native_matrix)[i * nb_in + j];
491  sum += FFABS(((int*)s->native_matrix)[i * nb_in + j]);
492  }
493  maxsum = FFMAX(maxsum, sum);
494  }
495  *((int*)s->native_one) = 32768;
496  if (maxsum <= 32768) {
497  s->mix_1_1_f = (mix_1_1_func_type*)copy_s16;
498  s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16;
499  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s);
500  } else {
501  s->mix_1_1_f = (mix_1_1_func_type*)copy_clip_s16;
502  s->mix_2_1_f = (mix_2_1_func_type*)sum2_clip_s16;
503  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_clip_s16(s);
504  }
505  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
506  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float));
507  s->native_one = av_mallocz(sizeof(float));
508  if (!s->native_matrix || !s->native_one)
509  return AVERROR(ENOMEM);
510  for (i = 0; i < nb_out; i++)
511  for (j = 0; j < nb_in; j++)
512  ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
513  *((float*)s->native_one) = 1.0;
514  s->mix_1_1_f = (mix_1_1_func_type*)copy_float;
515  s->mix_2_1_f = (mix_2_1_func_type*)sum2_float;
516  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s);
517  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
518  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
519  s->native_one = av_mallocz(sizeof(double));
520  if (!s->native_matrix || !s->native_one)
521  return AVERROR(ENOMEM);
522  for (i = 0; i < nb_out; i++)
523  for (j = 0; j < nb_in; j++)
524  ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
525  *((double*)s->native_one) = 1.0;
526  s->mix_1_1_f = (mix_1_1_func_type*)copy_double;
527  s->mix_2_1_f = (mix_2_1_func_type*)sum2_double;
528  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s);
529  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
530  s->native_one = av_mallocz(sizeof(int));
531  if (!s->native_one)
532  return AVERROR(ENOMEM);
533  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
534  if (!s->native_matrix) {
535  av_freep(&s->native_one);
536  return AVERROR(ENOMEM);
537  }
538  for (i = 0; i < nb_out; i++) {
539  double rem = 0;
540 
541  for (j = 0; j < nb_in; j++) {
542  double target = s->matrix[i][j] * 32768 + rem;
543  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
544  rem += target - ((int*)s->native_matrix)[i * nb_in + j];
545  }
546  }
547  *((int*)s->native_one) = 32768;
548  s->mix_1_1_f = (mix_1_1_func_type*)copy_s32;
549  s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32;
550  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s);
551  }else
552  av_assert0(0);
553  //FIXME quantize for integeres
554  for (i = 0; i < SWR_CH_MAX; i++) {
555  int ch_in=0;
556  for (j = 0; j < SWR_CH_MAX; j++) {
557  s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
558  if(s->matrix[i][j])
559  s->matrix_ch[i][++ch_in]= j;
560  }
561  s->matrix_ch[i][0]= ch_in;
562  }
563 
564 #if ARCH_X86 && HAVE_X86ASM && HAVE_MMX
565  return swri_rematrix_init_x86(s);
566 #endif
567 
568  return 0;
569 }
570 
572  av_freep(&s->native_matrix);
573  av_freep(&s->native_one);
574  av_freep(&s->native_simd_matrix);
575  av_freep(&s->native_simd_one);
576 }
577 
578 int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
579  int out_i, in_i, i, j;
580  int len1 = 0;
581  int off = 0;
582 
583  if(s->mix_any_f) {
584  s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len);
585  return 0;
586  }
587 
588  if(s->mix_2_1_simd || s->mix_1_1_simd){
589  len1= len&~15;
590  off = len1 * out->bps;
591  }
592 
593  av_assert0(s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || out->ch_count == s->out_ch_layout.nb_channels);
594  av_assert0(s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || in ->ch_count == s->in_ch_layout.nb_channels);
595 
596  for(out_i=0; out_i<out->ch_count; out_i++){
597  switch(s->matrix_ch[out_i][0]){
598  case 0:
599  if(mustcopy)
600  memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
601  break;
602  case 1:
603  in_i= s->matrix_ch[out_i][1];
604  if(s->matrix[out_i][in_i]!=1.0){
605  if(s->mix_1_1_simd && len1)
606  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);
607  if(len != len1)
608  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);
609  }else if(mustcopy){
610  memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
611  }else{
612  out->ch[out_i]= in->ch[in_i];
613  }
614  break;
615  case 2: {
616  int in_i1 = s->matrix_ch[out_i][1];
617  int in_i2 = s->matrix_ch[out_i][2];
618  if(s->mix_2_1_simd && len1)
619  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);
620  else
621  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);
622  if(len != len1)
623  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);
624  break;}
625  default:
626  if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){
627  for(i=0; i<len; i++){
628  float v=0;
629  for(j=0; j<s->matrix_ch[out_i][0]; j++){
630  in_i= s->matrix_ch[out_i][1+j];
631  v+= ((float*)in->ch[in_i])[i] * s->matrix_flt[out_i][in_i];
632  }
633  ((float*)out->ch[out_i])[i]= v;
634  }
635  }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
636  for(i=0; i<len; i++){
637  double v=0;
638  for(j=0; j<s->matrix_ch[out_i][0]; j++){
639  in_i= s->matrix_ch[out_i][1+j];
640  v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
641  }
642  ((double*)out->ch[out_i])[i]= v;
643  }
644  }else{
645  for(i=0; i<len; i++){
646  int v=0;
647  for(j=0; j<s->matrix_ch[out_i][0]; j++){
648  in_i= s->matrix_ch[out_i][1+j];
649  v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
650  }
651  ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
652  }
653  }
654  }
655  }
656  return 0;
657 }
mix_any_func_type
void() mix_any_func_type(uint8_t **out, const uint8_t **in1, void *coeffp, integer len)
Definition: swresample_internal.h:43
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:215
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
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
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:673
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:225
sane_layout
static int sane_layout(AVChannelLayout *ch_layout)
Definition: rematrix.c:106
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
AudioData
Definition: swresample_internal.h:45
fail
#define fail()
Definition: checkasm.h:193
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:209
even
static int even(int64_t layout)
Definition: rematrix.c:85
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
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:653
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:252
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:40
swri_rematrix
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy)
Definition: rematrix.c:578
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
auto_matrix
static av_cold int auto_matrix(SwrContext *s)
Definition: rematrix.c:436
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:345
AVMatrixEncoding
AVMatrixEncoding
Definition: channel_layout.h:260
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:132
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
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
mix_2_1_func_type
void() mix_2_1_func_type(void *out, const void *in1, const void *in2, void *coeffp, integer index1, integer index2, integer len)
Definition: swresample_internal.h:41
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
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:571
swresample_internal.h
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:809
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
mix_1_1_func_type
void() mix_1_1_func_type(void *out, const void *in, void *coeffp, integer index, integer len)
Definition: swresample_internal.h:40
FRONT_RIGHT_OF_CENTER
#define FRONT_RIGHT_OF_CENTER
Definition: rematrix.c:52
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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
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:104
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_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:256
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
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
stride
#define stride
Definition: h264pred_template.c:536
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:783
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:36
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:865
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:713
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:442
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:465
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:449
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:34
AVChannelLayout::u
union AVChannelLayout::@434 u
Details about which channels are present in this layout.
SIDE_RIGHT
#define SIDE_RIGHT
Definition: rematrix.c:55
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
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:91