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