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->order != AV_CHANNEL_ORDER_NATIVE)
108  return 0;
109  if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
110  return 0;
111  if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)))) // no asymetric front
112  return 0;
113  if(!even(av_channel_layout_subset(ch_layout, (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)))) // no asymetric side
114  return 0;
116  return 0;
118  return 0;
120  return 0;
121  if(ch_layout->nb_channels >= SWR_CH_MAX)
122  return 0;
123 
124  return 1;
125 }
126 
127 av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout,
128  double center_mix_level, double surround_mix_level,
129  double lfe_mix_level, double maxval,
130  double rematrix_volume, double *matrix_param,
131  ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
132 {
133  int i, j, out_i, ret;
134  AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 };
136  int64_t unaccounted;
137  double maxcoef=0;
138  char buf[128];
139 
140  ret = clean_layout(&in_ch_layout, in_layout, log_context);
141  ret |= clean_layout(&out_ch_layout, out_layout, log_context);
142  if (ret < 0)
143  goto fail;
144 
147  ) {
148  av_channel_layout_uninit(&out_ch_layout);
149  out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
150  }
153  ) {
154  av_channel_layout_uninit(&in_ch_layout);
156  }
160  av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
161  av_log(log_context, AV_LOG_WARNING,
162  "Full-on remixing from 22.2 has not yet been implemented! "
163  "Processing the input as '%s'\n",
164  buf);
165  }
166 
167  if(!av_channel_layout_check(&in_ch_layout)) {
168  av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n");
169  ret = AVERROR(EINVAL);
170  goto fail;
171  }
172  if(!sane_layout(&in_ch_layout)) {
173  av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
174  av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
175  ret = AVERROR(EINVAL);
176  goto fail;
177  }
178 
179  if(!av_channel_layout_check(&out_ch_layout)) {
180  av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n");
181  ret = AVERROR(EINVAL);
182  goto fail;
183  }
184  if(!sane_layout(&out_ch_layout)) {
185  av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf));
186  av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
187  ret = AVERROR(EINVAL);
188  goto fail;
189  }
190 
191  for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){
192  if( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0
193  && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0)
194  matrix[i][i]= 1.0;
195  }
196 
197  unaccounted = in_ch_layout.u.mask & ~out_ch_layout.u.mask;
198 
199 //FIXME implement dolby surround
200 //FIXME implement full ac3
201 
202 
203  if(unaccounted & AV_CH_FRONT_CENTER){
205  if (av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO)) {
206  matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level;
207  matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level;
208  } else {
211  }
212  }else
213  av_assert0(0);
214  }
215  if(unaccounted & AV_CH_LAYOUT_STEREO){
220  matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2);
221  }else
222  av_assert0(0);
223  }
224 
225  if(unaccounted & AV_CH_BACK_CENTER){
226  if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
229  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
232  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
233  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
234  matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
235  if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
236  matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
237  matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
238  } else {
239  matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
240  matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
241  }
242  } else {
243  matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
244  matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
245  }
246  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
247  matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
248  }else
249  av_assert0(0);
250  }
251  if(unaccounted & AV_CH_BACK_LEFT){
252  if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) {
255  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
256  if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) {
259  }else{
260  matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
261  matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
262  }
263  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
264  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
265  matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
266  matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
267  matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
268  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
269  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
270  matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
271  matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
272  matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
273  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
274  } else {
275  matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level;
276  matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
277  }
278  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
279  matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2;
280  matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2;
281  }else
282  av_assert0(0);
283  }
284 
285  if(unaccounted & AV_CH_SIDE_LEFT){
286  if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
287  /* if back channels do not exist in the input, just copy side
288  channels to back channels, otherwise mix side into back */
289  if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_BACK_LEFT) >= 0) {
292  } else {
293  matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
294  matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
295  }
296  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) {
299  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
300  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
301  matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
302  matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
303  matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
304  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
305  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
306  matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
307  matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
308  matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
309  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
310  } else {
311  matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level;
312  matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
313  }
314  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
315  matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2;
316  matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2;
317  }else
318  av_assert0(0);
319  }
320 
321  if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
322  if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
325  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
328  }else
329  av_assert0(0);
330  }
331 
332  if (unaccounted & AV_CH_TOP_FRONT_LEFT) {
337  matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2);
338  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
339  if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
342  } else {
343  matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += 1.0;
345  }
346  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) {
349  } else
350  av_assert0(0);
351  }
352 
353  /* mix LFE into front left/right or center */
354  if (unaccounted & AV_CH_LOW_FREQUENCY) {
356  matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level;
357  } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) {
358  matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
359  matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
360  } else
361  av_assert0(0);
362  }
363 
364  for(out_i=i=0; i<64; i++){
365  double sum=0;
366  int in_i=0;
367  if (av_channel_layout_index_from_channel(&out_ch_layout, i) < 0)
368  continue;
369  for(j=0; j<64; j++){
370  if (av_channel_layout_index_from_channel(&in_ch_layout, j) < 0)
371  continue;
372  if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0]))
373  matrix_param[stride*out_i + in_i] = matrix[i][j];
374  else
375  matrix_param[stride*out_i + in_i] = i == j &&
376  ( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0
377  && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0);
378  sum += fabs(matrix_param[stride*out_i + in_i]);
379  in_i++;
380  }
381  maxcoef= FFMAX(maxcoef, sum);
382  out_i++;
383  }
384  if(rematrix_volume < 0)
385  maxcoef = -rematrix_volume;
386 
387  if(maxcoef > maxval || rematrix_volume < 0){
388  maxcoef /= maxval;
389  for(i=0; i<SWR_CH_MAX; i++)
390  for(j=0; j<SWR_CH_MAX; j++){
391  matrix_param[stride*i + j] /= maxcoef;
392  }
393  }
394 
395  if(rematrix_volume > 0){
396  for(i=0; i<SWR_CH_MAX; i++)
397  for(j=0; j<SWR_CH_MAX; j++){
398  matrix_param[stride*i + j] *= rematrix_volume;
399  }
400  }
401 
402  av_log(log_context, AV_LOG_DEBUG, "Matrix coefficients:\n");
403  for (i = 0; i < out_ch_layout.nb_channels; i++){
404  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&out_ch_layout, i));
405  av_log(log_context, AV_LOG_DEBUG, "%s: ", buf);
406  for (j = 0; j < in_ch_layout.nb_channels; j++){
407  av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&in_ch_layout, j));
408  av_log(log_context, AV_LOG_DEBUG, "%s:%f ", buf, matrix_param[stride*i + j]);
409  }
410  av_log(log_context, AV_LOG_DEBUG, "\n");
411  }
412 
413  ret = 0;
414 fail:
415  av_channel_layout_uninit(&in_ch_layout);
416  av_channel_layout_uninit(&out_ch_layout);
417 
418  return ret;
419 }
420 
422 {
423  double maxval;
424  int ret;
425 
426  if (s->rematrix_maxval > 0) {
427  maxval = s->rematrix_maxval;
428  } else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
429  || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) {
430  maxval = 1.0;
431  } else
432  maxval = INT_MAX;
433 
434  memset(s->matrix, 0, sizeof(s->matrix));
435  ret = swr_build_matrix2(&s->in_ch_layout, &s->out_ch_layout,
436  s->clev, s->slev, s->lfe_mix_level,
437  maxval, s->rematrix_volume, (double*)s->matrix,
438  s->matrix[1] - s->matrix[0], s->matrix_encoding, s);
439 
440  if (ret >= 0 && s->int_sample_fmt == AV_SAMPLE_FMT_FLTP) {
441  int i, j;
442  for (i = 0; i < FF_ARRAY_ELEMS(s->matrix[0]); i++)
443  for (j = 0; j < FF_ARRAY_ELEMS(s->matrix[0]); j++)
444  s->matrix_flt[i][j] = s->matrix[i][j];
445  }
446 
447  return ret;
448 }
449 
451  int i, j;
452  int nb_in = s->used_ch_layout.nb_channels;
453  int nb_out = s->out.ch_count;
454 
455  s->mix_any_f = NULL;
456 
457  if (!s->rematrix_custom) {
458  int r = auto_matrix(s);
459  if (r)
460  return r;
461  }
462  if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
463  int maxsum = 0;
464  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
465  s->native_one = av_mallocz(sizeof(int));
466  if (!s->native_matrix || !s->native_one)
467  return AVERROR(ENOMEM);
468  for (i = 0; i < nb_out; i++) {
469  double rem = 0;
470  int sum = 0;
471 
472  for (j = 0; j < nb_in; j++) {
473  double target = s->matrix[i][j] * 32768 + rem;
474  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
475  rem += target - ((int*)s->native_matrix)[i * nb_in + j];
476  sum += FFABS(((int*)s->native_matrix)[i * nb_in + j]);
477  }
478  maxsum = FFMAX(maxsum, sum);
479  }
480  *((int*)s->native_one) = 32768;
481  if (maxsum <= 32768) {
482  s->mix_1_1_f = (mix_1_1_func_type*)copy_s16;
483  s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16;
484  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s);
485  } else {
486  s->mix_1_1_f = (mix_1_1_func_type*)copy_clip_s16;
487  s->mix_2_1_f = (mix_2_1_func_type*)sum2_clip_s16;
488  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_clip_s16(s);
489  }
490  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
491  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float));
492  s->native_one = av_mallocz(sizeof(float));
493  if (!s->native_matrix || !s->native_one)
494  return AVERROR(ENOMEM);
495  for (i = 0; i < nb_out; i++)
496  for (j = 0; j < nb_in; j++)
497  ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
498  *((float*)s->native_one) = 1.0;
499  s->mix_1_1_f = (mix_1_1_func_type*)copy_float;
500  s->mix_2_1_f = (mix_2_1_func_type*)sum2_float;
501  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s);
502  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
503  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
504  s->native_one = av_mallocz(sizeof(double));
505  if (!s->native_matrix || !s->native_one)
506  return AVERROR(ENOMEM);
507  for (i = 0; i < nb_out; i++)
508  for (j = 0; j < nb_in; j++)
509  ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
510  *((double*)s->native_one) = 1.0;
511  s->mix_1_1_f = (mix_1_1_func_type*)copy_double;
512  s->mix_2_1_f = (mix_2_1_func_type*)sum2_double;
513  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s);
514  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
515  s->native_one = av_mallocz(sizeof(int));
516  if (!s->native_one)
517  return AVERROR(ENOMEM);
518  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
519  if (!s->native_matrix) {
520  av_freep(&s->native_one);
521  return AVERROR(ENOMEM);
522  }
523  for (i = 0; i < nb_out; i++) {
524  double rem = 0;
525 
526  for (j = 0; j < nb_in; j++) {
527  double target = s->matrix[i][j] * 32768 + rem;
528  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
529  rem += target - ((int*)s->native_matrix)[i * nb_in + j];
530  }
531  }
532  *((int*)s->native_one) = 32768;
533  s->mix_1_1_f = (mix_1_1_func_type*)copy_s32;
534  s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32;
535  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s);
536  }else
537  av_assert0(0);
538  //FIXME quantize for integeres
539  for (i = 0; i < SWR_CH_MAX; i++) {
540  int ch_in=0;
541  for (j = 0; j < SWR_CH_MAX; j++) {
542  s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
543  if(s->matrix[i][j])
544  s->matrix_ch[i][++ch_in]= j;
545  }
546  s->matrix_ch[i][0]= ch_in;
547  }
548 
549 #if ARCH_X86 && HAVE_X86ASM && HAVE_MMX
550  return swri_rematrix_init_x86(s);
551 #endif
552 
553  return 0;
554 }
555 
557  av_freep(&s->native_matrix);
558  av_freep(&s->native_one);
559  av_freep(&s->native_simd_matrix);
560  av_freep(&s->native_simd_one);
561 }
562 
563 int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
564  int out_i, in_i, i, j;
565  int len1 = 0;
566  int off = 0;
567 
568  if(s->mix_any_f) {
569  s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len);
570  return 0;
571  }
572 
573  if(s->mix_2_1_simd || s->mix_1_1_simd){
574  len1= len&~15;
575  off = len1 * out->bps;
576  }
577 
578  av_assert0(s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || out->ch_count == s->out_ch_layout.nb_channels);
579  av_assert0(s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || in ->ch_count == s->in_ch_layout.nb_channels);
580 
581  for(out_i=0; out_i<out->ch_count; out_i++){
582  switch(s->matrix_ch[out_i][0]){
583  case 0:
584  if(mustcopy)
585  memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
586  break;
587  case 1:
588  in_i= s->matrix_ch[out_i][1];
589  if(s->matrix[out_i][in_i]!=1.0){
590  if(s->mix_1_1_simd && len1)
591  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);
592  if(len != len1)
593  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);
594  }else if(mustcopy){
595  memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
596  }else{
597  out->ch[out_i]= in->ch[in_i];
598  }
599  break;
600  case 2: {
601  int in_i1 = s->matrix_ch[out_i][1];
602  int in_i2 = s->matrix_ch[out_i][2];
603  if(s->mix_2_1_simd && len1)
604  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);
605  else
606  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);
607  if(len != len1)
608  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);
609  break;}
610  default:
611  if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){
612  for(i=0; i<len; i++){
613  float v=0;
614  for(j=0; j<s->matrix_ch[out_i][0]; j++){
615  in_i= s->matrix_ch[out_i][1+j];
616  v+= ((float*)in->ch[in_i])[i] * s->matrix_flt[out_i][in_i];
617  }
618  ((float*)out->ch[out_i])[i]= v;
619  }
620  }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
621  for(i=0; i<len; i++){
622  double v=0;
623  for(j=0; j<s->matrix_ch[out_i][0]; j++){
624  in_i= s->matrix_ch[out_i][1+j];
625  v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
626  }
627  ((double*)out->ch[out_i])[i]= v;
628  }
629  }else{
630  for(i=0; i<len; i++){
631  int v=0;
632  for(j=0; j<s->matrix_ch[out_i][0]; j++){
633  in_i= s->matrix_ch[out_i][1+j];
634  v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
635  }
636  ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
637  }
638  }
639  }
640  }
641  return 0;
642 }
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:186
AV_CH_LAYOUT_7POINT1_WIDE_BACK
#define AV_CH_LAYOUT_7POINT1_WIDE_BACK
Definition: channel_layout.h:229
AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
#define AV_CHANNEL_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:413
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:379
AVChannelLayout::u
union AVChannelLayout::@360 u
Details about which channels are present in this layout.
NUM_NAMED_CHANNELS
#define NUM_NAMED_CHANNELS
Definition: rematrix.c:63
matrix
Definition: vc1dsp.c:43
rematrix_template.c
AV_CH_TOP_FRONT_RIGHT
#define AV_CH_TOP_FRONT_RIGHT
Definition: channel_layout.h:182
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:665
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:196
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:180
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:308
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:335
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
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:179
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:172
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:205
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: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:246
TOP_FRONT_LEFT
#define TOP_FRONT_LEFT
Definition: rematrix.c:57
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:171
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:645
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
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:243
AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CH_LAYOUT_STEREO_DOWNMIX
Definition: channel_layout.h:239
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:563
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:421
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:73
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:127
AVMatrixEncoding
AVMatrixEncoding
Definition: channel_layout.h:244
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:170
AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
Definition: channel_layout.h:174
AV_CHANNEL_LAYOUT_22POINT2
#define AV_CHANNEL_LAYOUT_22POINT2
Definition: channel_layout.h:414
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:303
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:556
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:175
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:801
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:98
AV_CH_BACK_CENTER
#define AV_CH_BACK_CENTER
Definition: channel_layout.h:176
AV_CH_FRONT_LEFT
#define AV_CH_FRONT_LEFT
Definition: channel_layout.h:168
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:178
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:537
ret
ret
Definition: filter_design.txt:187
AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_SURROUND
Definition: channel_layout.h:208
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:775
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
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:857
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:705
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:433
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:450
AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_RIGHT
Definition: channel_layout.h:169
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:440
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:378
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
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:173
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:177
AV_MATRIX_ENCODING_DPLII
@ AV_MATRIX_ENCODING_DPLII
Definition: channel_layout.h:247
clean_layout
static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
Definition: rematrix.c:91