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