FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 #undef TEMPLATE_REMATRIX_S16
36 
37 #define TEMPLATE_REMATRIX_S32
38 #include "rematrix_template.c"
39 #undef TEMPLATE_REMATRIX_S32
40 
41 #define FRONT_LEFT 0
42 #define FRONT_RIGHT 1
43 #define FRONT_CENTER 2
44 #define LOW_FREQUENCY 3
45 #define BACK_LEFT 4
46 #define BACK_RIGHT 5
47 #define FRONT_LEFT_OF_CENTER 6
48 #define FRONT_RIGHT_OF_CENTER 7
49 #define BACK_CENTER 8
50 #define SIDE_LEFT 9
51 #define SIDE_RIGHT 10
52 #define TOP_CENTER 11
53 #define TOP_FRONT_LEFT 12
54 #define TOP_FRONT_CENTER 13
55 #define TOP_FRONT_RIGHT 14
56 #define TOP_BACK_LEFT 15
57 #define TOP_BACK_CENTER 16
58 #define TOP_BACK_RIGHT 17
59 
60 int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
61 {
62  int nb_in, nb_out, in, out;
63 
64  if (!s || s->in_convert) // s needs to be allocated but not initialized
65  return AVERROR(EINVAL);
66  memset(s->matrix, 0, sizeof(s->matrix));
69  for (out = 0; out < nb_out; out++) {
70  for (in = 0; in < nb_in; in++)
71  s->matrix[out][in] = matrix[in];
72  matrix += stride;
73  }
74  s->rematrix_custom = 1;
75  return 0;
76 }
77 
78 static int even(int64_t layout){
79  if(!layout) return 1;
80  if(layout&(layout-1)) return 1;
81  return 0;
82 }
83 
84 static int clean_layout(SwrContext *s, int64_t layout){
85  if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) {
86  char buf[128];
87  av_get_channel_layout_string(buf, sizeof(buf), -1, layout);
88  av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf);
89  return AV_CH_FRONT_CENTER;
90  }
91 
92  return layout;
93 }
94 
95 static int sane_layout(int64_t layout){
96  if(!(layout & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
97  return 0;
98  if(!even(layout & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT))) // no asymetric front
99  return 0;
100  if(!even(layout & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT))) // no asymetric side
101  return 0;
102  if(!even(layout & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)))
103  return 0;
105  return 0;
107  return 0;
108 
109  return 1;
110 }
111 
113 {
114  int i, j, out_i;
115  double matrix[64][64]={{0}};
116  int64_t unaccounted, in_ch_layout, out_ch_layout;
117  double maxcoef=0;
118  char buf[128];
119  const int matrix_encoding = s->matrix_encoding;
120  float maxval;
121 
122  in_ch_layout = clean_layout(s, s->in_ch_layout);
123  out_ch_layout = clean_layout(s, s->out_ch_layout);
124 
125  if( out_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX
126  && (in_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0
127  )
128  out_ch_layout = AV_CH_LAYOUT_STEREO;
129 
130  if( in_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX
131  && (out_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0
132  )
133  in_ch_layout = AV_CH_LAYOUT_STEREO;
134 
135  if(!sane_layout(in_ch_layout)){
136  av_get_channel_layout_string(buf, sizeof(buf), -1, s->in_ch_layout);
137  av_log(s, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
138  return AVERROR(EINVAL);
139  }
140 
141  if(!sane_layout(out_ch_layout)){
142  av_get_channel_layout_string(buf, sizeof(buf), -1, s->out_ch_layout);
143  av_log(s, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
144  return AVERROR(EINVAL);
145  }
146 
147  memset(s->matrix, 0, sizeof(s->matrix));
148  for(i=0; i<64; i++){
149  if(in_ch_layout & out_ch_layout & (1ULL<<i))
150  matrix[i][i]= 1.0;
151  }
152 
153  unaccounted= in_ch_layout & ~out_ch_layout;
154 
155 //FIXME implement dolby surround
156 //FIXME implement full ac3
157 
158 
159  if(unaccounted & AV_CH_FRONT_CENTER){
160  if((out_ch_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO){
161  if(in_ch_layout & AV_CH_LAYOUT_STEREO) {
162  matrix[ FRONT_LEFT][FRONT_CENTER]+= s->clev;
163  matrix[FRONT_RIGHT][FRONT_CENTER]+= s->clev;
164  } else {
165  matrix[ FRONT_LEFT][FRONT_CENTER]+= M_SQRT1_2;
167  }
168  }else
169  av_assert0(0);
170  }
171  if(unaccounted & AV_CH_LAYOUT_STEREO){
172  if(out_ch_layout & AV_CH_FRONT_CENTER){
173  matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2;
175  if(in_ch_layout & AV_CH_FRONT_CENTER)
176  matrix[FRONT_CENTER][ FRONT_CENTER] = s->clev*sqrt(2);
177  }else
178  av_assert0(0);
179  }
180 
181  if(unaccounted & AV_CH_BACK_CENTER){
182  if(out_ch_layout & AV_CH_BACK_LEFT){
183  matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2;
184  matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2;
185  }else if(out_ch_layout & AV_CH_SIDE_LEFT){
186  matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2;
187  matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2;
188  }else if(out_ch_layout & AV_CH_FRONT_LEFT){
189  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
190  matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
191  if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
192  matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev * M_SQRT1_2;
193  matrix[FRONT_RIGHT][BACK_CENTER] += s->slev * M_SQRT1_2;
194  } else {
195  matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev;
196  matrix[FRONT_RIGHT][BACK_CENTER] += s->slev;
197  }
198  } else {
199  matrix[ FRONT_LEFT][BACK_CENTER]+= s->slev*M_SQRT1_2;
200  matrix[FRONT_RIGHT][BACK_CENTER]+= s->slev*M_SQRT1_2;
201  }
202  }else if(out_ch_layout & AV_CH_FRONT_CENTER){
203  matrix[ FRONT_CENTER][BACK_CENTER]+= s->slev*M_SQRT1_2;
204  }else
205  av_assert0(0);
206  }
207  if(unaccounted & AV_CH_BACK_LEFT){
208  if(out_ch_layout & AV_CH_BACK_CENTER){
209  matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2;
210  matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2;
211  }else if(out_ch_layout & AV_CH_SIDE_LEFT){
212  if(in_ch_layout & AV_CH_SIDE_LEFT){
213  matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2;
214  matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2;
215  }else{
216  matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
217  matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
218  }
219  }else if(out_ch_layout & AV_CH_FRONT_LEFT){
220  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
221  matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * M_SQRT1_2;
222  matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
223  matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
224  matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * M_SQRT1_2;
225  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
226  matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * SQRT3_2;
227  matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
228  matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
229  matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * SQRT3_2;
230  } else {
231  matrix[ FRONT_LEFT][ BACK_LEFT] += s->slev;
232  matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev;
233  }
234  }else if(out_ch_layout & AV_CH_FRONT_CENTER){
235  matrix[ FRONT_CENTER][BACK_LEFT ]+= s->slev*M_SQRT1_2;
236  matrix[ FRONT_CENTER][BACK_RIGHT]+= s->slev*M_SQRT1_2;
237  }else
238  av_assert0(0);
239  }
240 
241  if(unaccounted & AV_CH_SIDE_LEFT){
242  if(out_ch_layout & AV_CH_BACK_LEFT){
243  /* if back channels do not exist in the input, just copy side
244  channels to back channels, otherwise mix side into back */
245  if (in_ch_layout & AV_CH_BACK_LEFT) {
246  matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2;
247  matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2;
248  } else {
249  matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
250  matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
251  }
252  }else if(out_ch_layout & AV_CH_BACK_CENTER){
253  matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2;
254  matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2;
255  }else if(out_ch_layout & AV_CH_FRONT_LEFT){
256  if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
257  matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * M_SQRT1_2;
258  matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
259  matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
260  matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * M_SQRT1_2;
261  } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
262  matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * SQRT3_2;
263  matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
264  matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
265  matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * SQRT3_2;
266  } else {
267  matrix[ FRONT_LEFT][ SIDE_LEFT] += s->slev;
268  matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev;
269  }
270  }else if(out_ch_layout & AV_CH_FRONT_CENTER){
271  matrix[ FRONT_CENTER][SIDE_LEFT ]+= s->slev*M_SQRT1_2;
272  matrix[ FRONT_CENTER][SIDE_RIGHT]+= s->slev*M_SQRT1_2;
273  }else
274  av_assert0(0);
275  }
276 
277  if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
278  if(out_ch_layout & AV_CH_FRONT_LEFT){
279  matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0;
280  matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0;
281  }else if(out_ch_layout & AV_CH_FRONT_CENTER){
284  }else
285  av_assert0(0);
286  }
287  /* mix LFE into front left/right or center */
288  if (unaccounted & AV_CH_LOW_FREQUENCY) {
289  if (out_ch_layout & AV_CH_FRONT_CENTER) {
291  } else if (out_ch_layout & AV_CH_FRONT_LEFT) {
294  } else
295  av_assert0(0);
296  }
297 
298  for(out_i=i=0; i<64; i++){
299  double sum=0;
300  int in_i=0;
301  for(j=0; j<64; j++){
302  s->matrix[out_i][in_i]= matrix[i][j];
303  if(matrix[i][j]){
304  sum += fabs(matrix[i][j]);
305  }
306  if(in_ch_layout & (1ULL<<j))
307  in_i++;
308  }
309  maxcoef= FFMAX(maxcoef, sum);
310  if(out_ch_layout & (1ULL<<i))
311  out_i++;
312  }
313  if(s->rematrix_volume < 0)
314  maxcoef = -s->rematrix_volume;
315 
316  if (s->rematrix_maxval > 0) {
317  maxval = s->rematrix_maxval;
320  maxval = 1.0;
321  } else
322  maxval = INT_MAX;
323 
324  if(maxcoef > maxval || s->rematrix_volume < 0){
325  maxcoef /= maxval;
326  for(i=0; i<SWR_CH_MAX; i++)
327  for(j=0; j<SWR_CH_MAX; j++){
328  s->matrix[i][j] /= maxcoef;
329  }
330  }
331 
332  if(s->rematrix_volume > 0){
333  for(i=0; i<SWR_CH_MAX; i++)
334  for(j=0; j<SWR_CH_MAX; j++){
335  s->matrix[i][j] *= s->rematrix_volume;
336  }
337  }
338 
339  for(i=0; i<av_get_channel_layout_nb_channels(out_ch_layout); i++){
340  for(j=0; j<av_get_channel_layout_nb_channels(in_ch_layout); j++){
341  av_log(NULL, AV_LOG_DEBUG, "%f ", s->matrix[i][j]);
342  }
343  av_log(NULL, AV_LOG_DEBUG, "\n");
344  }
345  return 0;
346 }
347 
349  int i, j;
352 
353  s->mix_any_f = NULL;
354 
355  if (!s->rematrix_custom) {
356  int r = auto_matrix(s);
357  if (r)
358  return r;
359  }
360  if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
361  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
362  s->native_one = av_mallocz(sizeof(int));
363  for (i = 0; i < nb_out; i++)
364  for (j = 0; j < nb_in; j++)
365  ((int*)s->native_matrix)[i * nb_in + j] = lrintf(s->matrix[i][j] * 32768);
366  *((int*)s->native_one) = 32768;
367  s->mix_1_1_f = (mix_1_1_func_type*)copy_s16;
368  s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16;
369  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s);
370  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
371  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float));
372  s->native_one = av_mallocz(sizeof(float));
373  for (i = 0; i < nb_out; i++)
374  for (j = 0; j < nb_in; j++)
375  ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
376  *((float*)s->native_one) = 1.0;
377  s->mix_1_1_f = (mix_1_1_func_type*)copy_float;
378  s->mix_2_1_f = (mix_2_1_func_type*)sum2_float;
379  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s);
380  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
381  s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
382  s->native_one = av_mallocz(sizeof(double));
383  for (i = 0; i < nb_out; i++)
384  for (j = 0; j < nb_in; j++)
385  ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
386  *((double*)s->native_one) = 1.0;
387  s->mix_1_1_f = (mix_1_1_func_type*)copy_double;
388  s->mix_2_1_f = (mix_2_1_func_type*)sum2_double;
389  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s);
390  }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
391  // Only for dithering currently
392 // s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
393  s->native_one = av_mallocz(sizeof(int));
394 // for (i = 0; i < nb_out; i++)
395 // for (j = 0; j < nb_in; j++)
396 // ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
397  *((int*)s->native_one) = 32768;
398  s->mix_1_1_f = (mix_1_1_func_type*)copy_s32;
399  s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32;
400  s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s);
401  }else
402  av_assert0(0);
403  //FIXME quantize for integeres
404  for (i = 0; i < SWR_CH_MAX; i++) {
405  int ch_in=0;
406  for (j = 0; j < SWR_CH_MAX; j++) {
407  s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
408  if(s->matrix[i][j])
409  s->matrix_ch[i][++ch_in]= j;
410  }
411  s->matrix_ch[i][0]= ch_in;
412  }
413 
414  if(HAVE_YASM && HAVE_MMX) swri_rematrix_init_x86(s);
415 
416  return 0;
417 }
418 
420  av_freep(&s->native_matrix);
421  av_freep(&s->native_one);
424 }
425 
426 int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
427  int out_i, in_i, i, j;
428  int len1 = 0;
429  int off = 0;
430 
431  if(s->mix_any_f) {
432  s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len);
433  return 0;
434  }
435 
436  if(s->mix_2_1_simd || s->mix_1_1_simd){
437  len1= len&~15;
438  off = len1 * out->bps;
439  }
440 
442  av_assert0(!s-> in_ch_layout || in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout));
443 
444  for(out_i=0; out_i<out->ch_count; out_i++){
445  switch(s->matrix_ch[out_i][0]){
446  case 0:
447  if(mustcopy)
448  memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
449  break;
450  case 1:
451  in_i= s->matrix_ch[out_i][1];
452  if(s->matrix[out_i][in_i]!=1.0){
453  if(s->mix_1_1_simd && len1)
454  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);
455  if(len != len1)
456  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);
457  }else if(mustcopy){
458  memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
459  }else{
460  out->ch[out_i]= in->ch[in_i];
461  }
462  break;
463  case 2: {
464  int in_i1 = s->matrix_ch[out_i][1];
465  int in_i2 = s->matrix_ch[out_i][2];
466  if(s->mix_2_1_simd && len1)
467  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);
468  else
469  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);
470  if(len != len1)
471  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);
472  break;}
473  default:
475  for(i=0; i<len; i++){
476  float v=0;
477  for(j=0; j<s->matrix_ch[out_i][0]; j++){
478  in_i= s->matrix_ch[out_i][1+j];
479  v+= ((float*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
480  }
481  ((float*)out->ch[out_i])[i]= v;
482  }
483  }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
484  for(i=0; i<len; i++){
485  double v=0;
486  for(j=0; j<s->matrix_ch[out_i][0]; j++){
487  in_i= s->matrix_ch[out_i][1+j];
488  v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
489  }
490  ((double*)out->ch[out_i])[i]= v;
491  }
492  }else{
493  for(i=0; i<len; i++){
494  int v=0;
495  for(j=0; j<s->matrix_ch[out_i][0]; j++){
496  in_i= s->matrix_ch[out_i][1+j];
497  v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
498  }
499  ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
500  }
501  }
502  }
503  }
504  return 0;
505 }