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 
25 #define TEMPLATE_REMATRIX_FLT
26 #include "rematrix_template.c"
27 #undef TEMPLATE_REMATRIX_FLT
28 
29 #define TEMPLATE_REMATRIX_DBL
30 #include "rematrix_template.c"
31 #undef TEMPLATE_REMATRIX_DBL
32 
33 #define TEMPLATE_REMATRIX_S16
34 #include "rematrix_template.c"
35 #define TEMPLATE_CLIP
36 #include "rematrix_template.c"
37 #undef TEMPLATE_CLIP
38 #undef TEMPLATE_REMATRIX_S16
39 
40 #define TEMPLATE_REMATRIX_S32
41 #include "rematrix_template.c"
42 #undef TEMPLATE_REMATRIX_S32
43 
44 #define FRONT_LEFT 0
45 #define FRONT_RIGHT 1
46 #define FRONT_CENTER 2
47 #define LOW_FREQUENCY 3
48 #define BACK_LEFT 4
49 #define BACK_RIGHT 5
50 #define FRONT_LEFT_OF_CENTER 6
51 #define FRONT_RIGHT_OF_CENTER 7
52 #define BACK_CENTER 8
53 #define SIDE_LEFT 9
54 #define SIDE_RIGHT 10
55 #define TOP_CENTER 11
56 #define TOP_FRONT_LEFT 12
57 #define TOP_FRONT_CENTER 13
58 #define TOP_FRONT_RIGHT 14
59 #define TOP_BACK_LEFT 15
60 #define TOP_BACK_CENTER 16
61 #define TOP_BACK_RIGHT 17
62 #define NUM_NAMED_CHANNELS 18
63 
64 int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
65 {
66  int nb_in, nb_out, in, out;
67  int user_in_chlayout_nb_channels, user_out_chlayout_nb_channels;
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 #if FF_API_OLD_CHANNEL_LAYOUT
76  user_in_chlayout_nb_channels = av_get_channel_layout_nb_channels(s->user_in_ch_layout);
78  if (!user_in_chlayout_nb_channels)
79 #endif
80  user_in_chlayout_nb_channels = s->user_in_chlayout.nb_channels;
81  nb_in =
82 #if FF_API_OLD_CHANNEL_LAYOUT
83  (s->user_in_ch_count > 0) ? s->user_in_ch_count :
84 #endif
85  user_in_chlayout_nb_channels;
88  user_out_chlayout_nb_channels = av_get_channel_layout_nb_channels(s->user_out_ch_layout);
90  if (!user_out_chlayout_nb_channels)
91 #endif
92  user_out_chlayout_nb_channels = s->user_out_chlayout.nb_channels;
93  nb_out =
94 #if FF_API_OLD_CHANNEL_LAYOUT
95  (s->user_out_ch_count > 0) ? s->user_out_ch_count :
96 #endif
97  user_out_chlayout_nb_channels;
98  for (out = 0; out < nb_out; out++) {
99  for (in = 0; in < nb_in; in++)
100  s->matrix_flt[out][in] = s->matrix[out][in] = matrix[in];
101  matrix += stride;
102  }
103  s->rematrix_custom = 1;
104  return 0;
105 }
106 
107 static int even(int64_t layout){
108  if(!layout) return 1;
109  if(layout&(layout-1)) return 1;
110  return 0;
111 }
112 
113 static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
114 {
115  int ret = 0;
116 
118  char buf[128];
119  av_channel_layout_describe(in, buf, sizeof(buf));
120  av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf);
122  } else
124 
125  return ret;
126 }
127 
128 static int sane_layout(AVChannelLayout *ch_layout) {
129  if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE)
130  return 0;
131  if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
132  return 0;
133  if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)))) // no asymetric front
134  return 0;
135  if(!even(av_channel_layout_subset(ch_layout, (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)))) // no asymetric side
136  return 0;
138  return 0;
140  return 0;
142  return 0;
143  if(ch_layout->nb_channels >= SWR_CH_MAX)
144  return 0;
145 
146  return 1;
147 }
148 
149 #if FF_API_OLD_CHANNEL_LAYOUT
150 av_cold int swr_build_matrix(uint64_t in_ch_layout_param, uint64_t out_ch_layout_param,
151  double center_mix_level, double surround_mix_level,
152  double lfe_mix_level, double maxval,
153  double rematrix_volume, double *matrix_param,
154  int stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
155 {
156  AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 };
157  int ret;
158 
159  ret = av_channel_layout_from_mask(&in_ch_layout, in_ch_layout_param);
160  ret |= av_channel_layout_from_mask(&out_ch_layout, out_ch_layout_param);
161  if (ret < 0)
162  return ret;
163 
164  return swr_build_matrix2(&in_ch_layout, &out_ch_layout, center_mix_level, surround_mix_level,
165  lfe_mix_level, maxval, rematrix_volume, matrix_param,
166  stride, matrix_encoding, log_context);
167 }
168 #endif
169 
170 av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout,
171  double center_mix_level, double surround_mix_level,
172  double lfe_mix_level, double maxval,
173  double rematrix_volume, double *matrix_param,
174  ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
175 {
176  int i, j, out_i, ret;
177  AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 };
179  int64_t unaccounted;
180  double maxcoef=0;
181  char buf[128];
182 
183  ret = clean_layout(&in_ch_layout, in_layout, log_context);
184  ret |= clean_layout(&out_ch_layout, out_layout, log_context);
185  if (ret < 0)
186  goto fail;
187 
190  ) {
191  av_channel_layout_uninit(&out_ch_layout);
192  out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
193  }
196  ) {
197  av_channel_layout_uninit(&in_ch_layout);
199  }
203  av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
204  av_log(log_context, AV_LOG_WARNING,
205  "Full-on remixing from 22.2 has not yet been implemented! "
206  "Processing the input as '%s'\n",
207  buf);
208  }
209 
210  if(!av_channel_layout_check(&in_ch_layout)) {
211  av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n");
212  ret = AVERROR(EINVAL);
213  goto fail;
214  }
215  if(!sane_layout(&in_ch_layout)) {
216  av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
217  av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
218  ret = AVERROR(EINVAL);
219  goto fail;
220  }
221 
222  if(!av_channel_layout_check(&out_ch_layout)) {
223  av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n");
224  ret = AVERROR(EINVAL);
225  goto fail;
226  }
227  if(!sane_layout(&out_ch_layout)) {
228  av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf));
229  av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
230  ret = AVERROR(EINVAL);
231  goto fail;
232  }
233 
234  for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){
235  if( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0
236  && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0)
237  matrix[i][i]= 1.0;
238  }
239 
240  unaccounted = in_ch_layout.u.mask & ~out_ch_layout.u.mask;
241 
242 //FIXME implement dolby surround
243 //FIXME implement full ac3
244 
245 
246  if(unaccounted & AV_CH_FRONT_CENTER){
248  if (av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO)) {
249  matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level;
250  matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level;
251  } else {
254  }
255  }else
256  av_assert0(0);
257  }
258  if(unaccounted & AV_CH_LAYOUT_STEREO){
263  matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2);
264  }else
265  av_assert0(0);
266  }
267 
268  if(unaccounted & AV_CH_BACK_CENTER){
269  if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
272  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
275  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
276  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
277  matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
278  if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
279  matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
280  matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
281  } else {
282  matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
283  matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
284  }
285  } else {
286  matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
287  matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
288  }
289  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
290  matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
291  }else
292  av_assert0(0);
293  }
294  if(unaccounted & AV_CH_BACK_LEFT){
295  if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) {
298  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
299  if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
302  }else{
303  matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
304  matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
305  }
306  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
307  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
308  matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
309  matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
310  matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
311  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
312  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
313  matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
314  matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
315  matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
316  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
317  } else {
318  matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level;
319  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
320  }
321  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
322  matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2;
323  matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2;
324  }else
325  av_assert0(0);
326  }
327 
328  if(unaccounted & AV_CH_SIDE_LEFT){
329  if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
330  /* if back channels do not exist in the input, just copy side
331  channels to back channels, otherwise mix side into back */
332  if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
335  } else {
336  matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
337  matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
338  }
339  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) {
342  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
343  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
344  matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
345  matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
346  matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
347  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
348  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
349  matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
350  matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
351  matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
352  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
353  } else {
354  matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level;
355  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
356  }
357  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
358  matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2;
359  matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2;
360  }else
361  av_assert0(0);
362  }
363 
364  if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
365  if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
368  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
371  }else
372  av_assert0(0);
373  }
374 
375  if (unaccounted & AV_CH_TOP_FRONT_LEFT) {
380  matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2);
381  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
382  if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
385  } else {
386  matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += 1.0;
388  }
389  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
392  } else
393  av_assert0(0);
394  }
395 
396  /* mix LFE into front left/right or center */
397  if (unaccounted & AV_CH_LOW_FREQUENCY) {
399  matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level;
400  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
401  matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
402  matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
403  } else
404  av_assert0(0);
405  }
406 
407  for(out_i=i=0; i<64; i++){
408  double sum=0;
409  int in_i=0;
410  if (av_channel_layout_index_from_channel(&out_ch_layout, i) < 0)
411  continue;
412  for(j=0; j<64; j++){
413  if (av_channel_layout_index_from_channel(&in_ch_layout, j) < 0)
414  continue;
415  if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0]))
416  matrix_param[stride*out_i + in_i] = matrix[i][j];
417  else
418  matrix_param[stride*out_i + in_i] = i == j &&
419  ( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0
420  && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0);
421  sum += fabs(matrix_param[stride*out_i + in_i]);
422  in_i++;
423  }
424  maxcoef= FFMAX(maxcoef, sum);
425  out_i++;
426  }
427  if(rematrix_volume < 0)
428  maxcoef = -rematrix_volume;
429 
430  if(maxcoef > maxval || rematrix_volume < 0){
431  maxcoef /= maxval;
432  for(i=0; i<SWR_CH_MAX; i++)
433  for(j=0; j<SWR_CH_MAX; j++){
434  matrix_param[stride*i + j] /= maxcoef;
435  }
436  }
437 
438  if(rematrix_volume > 0){
439  for(i=0; i<SWR_CH_MAX; i++)
440  for(j=0; j<SWR_CH_MAX; j++){
441  matrix_param[stride*i + j] *= rematrix_volume;
442  }
443  }
444 
445  av_log(log_context, AV_LOG_DEBUG, "Matrix coefficients:\n");
446  for (i = 0; i < out_ch_layout.nb_channels; i++){
447  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&out_ch_layout, i));
448  av_log(log_context, AV_LOG_DEBUG, "%s: ", buf);
449  for (j = 0; j < in_ch_layout.nb_channels; j++){
450  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&in_ch_layout, j));
451  av_log(log_context, AV_LOG_DEBUG, "%s:%f ", buf, matrix_param[stride*i + j]);
452  }
453  av_log(log_context, AV_LOG_DEBUG, "\n");
454  }
455 
456  ret = 0;
457 fail:
458  av_channel_layout_uninit(&in_ch_layout);
459  av_channel_layout_uninit(&out_ch_layout);
460 
461  return ret;
462 }
463 
465 {
466  double maxval;
467  int ret;
468 
469  if (s->rematrix_maxval > 0) {
470  maxval = s->rematrix_maxval;
471  } else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
472  || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) {
473  maxval = 1.0;
474  } else
475  maxval = INT_MAX;
476 
477  memset(s->matrix, 0, sizeof(s->matrix));
478  ret = swr_build_matrix2(&s->in_ch_layout, &s->out_ch_layout,
479  s->clev, s->slev, s->lfe_mix_level,
480  maxval, s->rematrix_volume, (double*)s->matrix,
481  s->matrix[1] - s->matrix[0], s->matrix_encoding, s);
482 
483  if (ret >= 0 && s->int_sample_fmt == AV_SAMPLE_FMT_FLTP) {
484  int i, j;
485  for (i = 0; i < FF_ARRAY_ELEMS(s->matrix[0]); i++)
486  for (j = 0; j < FF_ARRAY_ELEMS(s->matrix[0]); j++)
487  s->matrix_flt[i][j] = s->matrix[i][j];
488  }
489 
490  return ret;
491 }
492 
494  int i, j;
495  int nb_in = s->used_ch_layout.nb_channels;
496  int nb_out = s->out.ch_count;
497 
498  s->mix_any_f = NULL;
499 
500  if (!s->rematrix_custom) {
501  int r = auto_matrix(s);
502  if (r)
503  return r;
504  }
505  if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
506  int maxsum = 0;
507  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
508  s->native_one = av_mallocz(sizeof(int));
509  if (!s->native_matrix || !s->native_one)
510  return AVERROR(ENOMEM);
511  for (i = 0; i < nb_out; i++) {
512  double rem = 0;
513  int sum = 0;
514 
515  for (j = 0; j < nb_in; j++) {
516  double target = s->matrix[i][j] * 32768 + rem;
517  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
518  rem += target - ((int*)s->native_matrix)[i * nb_in + j];
519  sum += FFABS(((int*)s->native_matrix)[i * nb_in + j]);
520  }
521  maxsum = FFMAX(maxsum, sum);
522  }
523  *((int*)s->native_one) = 32768;
524  if (maxsum <= 32768) {
525  s->mix_1_1_f = (mix_1_1_func_type*)copy_s16;
526  s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16;
527  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s);
528  } else {
529  s->mix_1_1_f = (mix_1_1_func_type*)copy_clip_s16;
530  s->mix_2_1_f = (mix_2_1_func_type*)sum2_clip_s16;
531  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_clip_s16(s);
532  }
533  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
534  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float));
535  s->native_one = av_mallocz(sizeof(float));
536  if (!s->native_matrix || !s->native_one)
537  return AVERROR(ENOMEM);
538  for (i = 0; i < nb_out; i++)
539  for (j = 0; j < nb_in; j++)
540  ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
541  *((float*)s->native_one) = 1.0;
542  s->mix_1_1_f = (mix_1_1_func_type*)copy_float;
543  s->mix_2_1_f = (mix_2_1_func_type*)sum2_float;
544  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s);
545  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
546  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
547  s->native_one = av_mallocz(sizeof(double));
548  if (!s->native_matrix || !s->native_one)
549  return AVERROR(ENOMEM);
550  for (i = 0; i < nb_out; i++)
551  for (j = 0; j < nb_in; j++)
552  ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
553  *((double*)s->native_one) = 1.0;
554  s->mix_1_1_f = (mix_1_1_func_type*)copy_double;
555  s->mix_2_1_f = (mix_2_1_func_type*)sum2_double;
556  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s);
557  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
558  s->native_one = av_mallocz(sizeof(int));
559  if (!s->native_one)
560  return AVERROR(ENOMEM);
561  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
562  if (!s->native_matrix) {
563  av_freep(&s->native_one);
564  return AVERROR(ENOMEM);
565  }
566  for (i = 0; i < nb_out; i++) {
567  double rem = 0;
568 
569  for (j = 0; j < nb_in; j++) {
570  double target = s->matrix[i][j] * 32768 + rem;
571  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
572  rem += target - ((int*)s->native_matrix)[i * nb_in + j];
573  }
574  }
575  *((int*)s->native_one) = 32768;
576  s->mix_1_1_f = (mix_1_1_func_type*)copy_s32;
577  s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32;
578  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s);
579  }else
580  av_assert0(0);
581  //FIXME quantize for integeres
582  for (i = 0; i < SWR_CH_MAX; i++) {
583  int ch_in=0;
584  for (j = 0; j < SWR_CH_MAX; j++) {
585  s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
586  if(s->matrix[i][j])
587  s->matrix_ch[i][++ch_in]= j;
588  }
589  s->matrix_ch[i][0]= ch_in;
590  }
591 
592 #if ARCH_X86 && HAVE_X86ASM && HAVE_MMX
593  return swri_rematrix_init_x86(s);
594 #endif
595 
596  return 0;
597 }
598 
600  av_freep(&s->native_matrix);
601  av_freep(&s->native_one);
602  av_freep(&s->native_simd_matrix);
603  av_freep(&s->native_simd_one);
604 }
605 
606 int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
607  int out_i, in_i, i, j;
608  int len1 = 0;
609  int off = 0;
610 
611  if(s->mix_any_f) {
612  s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len);
613  return 0;
614  }
615 
616  if(s->mix_2_1_simd || s->mix_1_1_simd){
617  len1= len&~15;
618  off = len1 * out->bps;
619  }
620 
621  av_assert0(s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || out->ch_count == s->out_ch_layout.nb_channels);
622  av_assert0(s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || in ->ch_count == s->in_ch_layout.nb_channels);
623 
624  for(out_i=0; out_i<out->ch_count; out_i++){
625  switch(s->matrix_ch[out_i][0]){
626  case 0:
627  if(mustcopy)
628  memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
629  break;
630  case 1:
631  in_i= s->matrix_ch[out_i][1];
632  if(s->matrix[out_i][in_i]!=1.0){
633  if(s->mix_1_1_simd && len1)
634  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);
635  if(len != len1)
636  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);
637  }else if(mustcopy){
638  memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
639  }else{
640  out->ch[out_i]= in->ch[in_i];
641  }
642  break;
643  case 2: {
644  int in_i1 = s->matrix_ch[out_i][1];
645  int in_i2 = s->matrix_ch[out_i][2];
646  if(s->mix_2_1_simd && len1)
647  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);
648  else
649  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);
650  if(len != len1)
651  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);
652  break;}
653  default:
654  if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){
655  for(i=0; i<len; i++){
656  float v=0;
657  for(j=0; j<s->matrix_ch[out_i][0]; j++){
658  in_i= s->matrix_ch[out_i][1+j];
659  v+= ((float*)in->ch[in_i])[i] * s->matrix_flt[out_i][in_i];
660  }
661  ((float*)out->ch[out_i])[i]= v;
662  }
663  }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
664  for(i=0; i<len; i++){
665  double v=0;
666  for(j=0; j<s->matrix_ch[out_i][0]; j++){
667  in_i= s->matrix_ch[out_i][1+j];
668  v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
669  }
670  ((double*)out->ch[out_i])[i]= v;
671  }
672  }else{
673  for(i=0; i<len; i++){
674  int v=0;
675  for(j=0; j<s->matrix_ch[out_i][0]; j++){
676  in_i= s->matrix_ch[out_i][1+j];
677  v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
678  }
679  ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
680  }
681  }
682  }
683  }
684  return 0;
685 }
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
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
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:186
AV_CH_LAYOUT_7POINT1_WIDE_BACK
#define AV_CH_LAYOUT_7POINT1_WIDE_BACK
Definition: channel_layout.h:235
AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:415
r
const char * r
Definition: vf_curves.c:126
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:54
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:383
NUM_NAMED_CHANNELS
#define NUM_NAMED_CHANNELS
Definition: rematrix.c:62
matrix
Definition: vc1dsp.c:42
rematrix_template.c
AV_CH_TOP_FRONT_RIGHT
#define AV_CH_TOP_FRONT_RIGHT
Definition: channel_layout.h:178
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:806
TOP_FRONT_RIGHT
#define TOP_FRONT_RIGHT
Definition: rematrix.c:58
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:196
sane_layout
static int sane_layout(AVChannelLayout *ch_layout)
Definition: rematrix.c:128
AV_CH_TOP_FRONT_LEFT
#define AV_CH_TOP_FRONT_LEFT
Definition: channel_layout.h:176
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:312
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVChannelLayout::mask
uint64_t mask
This member must be used for AV_CHANNEL_ORDER_NATIVE, and may be used for AV_CHANNEL_ORDER_AMBISONIC ...
Definition: channel_layout.h:339
av_get_channel_layout_nb_channels
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
Definition: channel_layout.c:328
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:317
swr_set_matrix
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
Set a customized remix matrix.
Definition: rematrix.c:64
AudioData
Definition: swresample_internal.h:45
fail
#define fail()
Definition: checkasm.h:138
FRONT_LEFT_OF_CENTER
#define FRONT_LEFT_OF_CENTER
Definition: rematrix.c:50
AV_CH_BACK_LEFT
#define AV_CH_BACK_LEFT
Definition: channel_layout.h:168
AVChannelLayout::u
union AVChannelLayout::@332 u
Details about which channels are present in this layout.
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:211
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
even
static int even(int64_t layout)
Definition: rematrix.c:107
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:250
TOP_FRONT_LEFT
#define TOP_FRONT_LEFT
Definition: rematrix.c:56
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:167
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:786
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:112
av_channel_layout_from_mask
FF_ENABLE_DEPRECATION_WARNINGS 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:399
AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CH_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:243
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:606
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
auto_matrix
static av_cold int auto_matrix(SwrContext *s)
Definition: rematrix.c:464
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:45
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:65
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:170
AVMatrixEncoding
AVMatrixEncoding
Definition: channel_layout.h:248
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
AV_CH_FRONT_CENTER
#define AV_CH_FRONT_CENTER
Definition: channel_layout.h:166
AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
Definition: channel_layout.h:170
AV_CHANNEL_LAYOUT_22POINT2
#define AV_CHANNEL_LAYOUT_22POINT2
Definition: channel_layout.h:416
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:48
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:307
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
FF_API_OLD_CHANNEL_LAYOUT
#define FF_API_OLD_CHANNEL_LAYOUT
Definition: version.h:111
BACK_RIGHT
#define BACK_RIGHT
Definition: rematrix.c:49
AV_CHAN_SIDE_LEFT
@ AV_CHAN_SIDE_LEFT
Definition: channel_layout.h:59
SIDE_LEFT
#define SIDE_LEFT
Definition: rematrix.c:53
swri_rematrix_free
av_cold void swri_rematrix_free(SwrContext *s)
Definition: rematrix.c:599
swresample_internal.h
AV_CHANNEL_ORDER_NATIVE
@ AV_CHANNEL_ORDER_NATIVE
The native channel order, i.e.
Definition: channel_layout.h:118
AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
Definition: channel_layout.h:171
FRONT_CENTER
#define FRONT_CENTER
Definition: rematrix.c:46
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:942
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:51
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
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:101
AV_CH_BACK_CENTER
#define AV_CH_BACK_CENTER
Definition: channel_layout.h:172
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:164
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:254
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:174
len
int len
Definition: vorbis_enc_data.h:426
FRONT_LEFT
#define FRONT_LEFT
Definition: rematrix.c:44
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
stride
#define stride
Definition: h264pred_template.c:537
ret
ret
Definition: filter_design.txt:187
AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_SURROUND
Definition: channel_layout.h:214
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:916
AV_CHAN_BACK_CENTER
@ AV_CHAN_BACK_CENTER
Definition: channel_layout.h:58
TOP_FRONT_CENTER
#define TOP_FRONT_CENTER
Definition: rematrix.c:57
M_SQRT1_2
#define M_SQRT1_2
Definition: mathematics.h:103
SWR_CH_MAX
#define SWR_CH_MAX
Definition: af_amerge.c:36
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:998
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:846
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:640
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:493
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:165
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:647
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
AV_CHAN_TOP_FRONT_CENTER
@ AV_CHAN_TOP_FRONT_CENTER
Definition: channel_layout.h:63
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:382
LOW_FREQUENCY
#define LOW_FREQUENCY
Definition: rematrix.c:47
BACK_CENTER
#define BACK_CENTER
Definition: rematrix.c:52
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
SIDE_RIGHT
#define SIDE_RIGHT
Definition: rematrix.c:54
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_CH_BACK_RIGHT
#define AV_CH_BACK_RIGHT
Definition: channel_layout.h:169
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
AV_CH_SIDE_LEFT
#define AV_CH_SIDE_LEFT
Definition: channel_layout.h:173
AV_MATRIX_ENCODING_DPLII
@ AV_MATRIX_ENCODING_DPLII
Definition: channel_layout.h:251
clean_layout
static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
Definition: rematrix.c:113