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_calloc(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_calloc(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_calloc(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 
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 }
struct AudioConvert * in_convert
input conversion context
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
#define BACK_RIGHT
Definition: rematrix.c:42
float v
const char * s
Definition: avisynth_c.h:668
#define FRONT_RIGHT
Definition: rematrix.c:38
#define HAVE_YASM
Definition: config.h:115
enum AVSampleFormat int_sample_fmt
internal sample format (AV_SAMPLE_FMT_FLTP or AV_SAMPLE_FMT_S16P)
Audio buffer used for intermediate storage between conversion phases.
Definition: oss_audio.c:46
#define FRONT_RIGHT_OF_CENTER
Definition: rematrix.c:44
#define AV_CH_LAYOUT_SURROUND
int ch_count
number of channels
#define M_SQRT1_2
Definition: mathematics.h:49
int rematrix_custom
flag to indicate that a custom matrix has been defined
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy)
Definition: rematrix.c:393
#define LOW_FREQUENCY
Definition: rematrix.c:40
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL),};static void cpy1(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, len);}static void cpy2(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 2 *len);}static void cpy4(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 4 *len);}static void cpy8(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;}}if(HAVE_YASM &&HAVE_MMX) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);return ctx;}void swri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len){int ch;int off=0;const int os=(out->planar?1:out->ch_count)*out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){int planes=in->planar?in->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){int planes=out->planar?out-> ch_count
#define AV_CH_LAYOUT_STEREO
#define SQRT3_2
int stride
Definition: mace.c:144
#define SIDE_RIGHT
Definition: rematrix.c:47
void( mix_2_1_func_type)(void *out, const void *in1, const void *in2, void *coeffp, integer index1, integer index2, integer len)
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
av_cold int swri_rematrix_init(SwrContext *s)
Definition: rematrix.c:327
uint8_t
#define av_cold
Definition: attributes.h:78
enum AVSampleFormat fmt
sample format
#define BACK_CENTER
Definition: rematrix.c:45
#define AV_CH_LOW_FREQUENCY
#define lrintf(x)
Definition: libm_mips.h:70
#define AV_CH_BACK_LEFT
integer sqrt
Definition: avutil.txt:2
enum AVSampleFormat out_sample_fmt
output sample format
float, planar
Definition: samplefmt.h:60
float slev
surround mixing level
#define FRONT_CENTER
Definition: rematrix.c:39
#define SIDE_LEFT
Definition: rematrix.c:46
const char * r
Definition: vf_curves.c:94
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
float clev
center mixing level
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
void( mix_any_func_type)(uint8_t **out, const uint8_t **in1, void *coeffp, integer len)
mix_2_1_func_type * mix_2_1_simd
#define FFMAX(a, b)
Definition: common.h:56
int32_t matrix32[SWR_CH_MAX][SWR_CH_MAX]
17.15 fixed point rematrixing coefficients
AudioData midbuf
intermediate audio data (postin/preout)
#define AV_LOG_VERBOSE
Definition: log.h:157
void swri_rematrix_init_x86(struct SwrContext *s)
audio channel layout utility functions
#define AV_CH_LAYOUT_STEREO_DOWNMIX
#define FRONT_LEFT_OF_CENTER
Definition: rematrix.c:43
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
Set a customized remix matrix.
Definition: rematrix.c:56
mix_1_1_func_type * mix_1_1_f
mix_1_1_func_type * mix_1_1_simd
int64_t out_ch_layout
output channel layout
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition: samplefmt.c:73
enum AVMatrixEncoding matrix_encoding
matrixed stereo encoding
int bps
bytes per sample
#define AV_CH_FRONT_LEFT_OF_CENTER
uint8_t * native_matrix
mix_any_func_type * mix_any_f
#define AV_CH_FRONT_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:104
NULL
Definition: eval.c:55
static av_cold int auto_matrix(SwrContext *s)
Definition: rematrix.c:111
#define AV_CH_FRONT_LEFT
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
static int clean_layout(SwrContext *s, int64_t layout)
Definition: rematrix.c:80
synthesis window for stochastic i
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
static int sane_layout(int64_t layout)
Definition: rematrix.c:94
#define BACK_LEFT
Definition: rematrix.c:41
void * av_calloc(size_t nmemb, size_t size)
Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vec...
Definition: mem.c:213
#define AV_CH_BACK_CENTER
uint8_t * native_one
#define AV_CH_SIDE_RIGHT
void( mix_1_1_func_type)(void *out, const void *in, void *coeffp, integer index, integer len)
int64_t in_ch_layout
input channel layout
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
uint8_t * native_simd_matrix
#define SWR_CH_MAX
Maximum number of channels.
Definition: swresample.h:102
float lfe_mix_level
LFE mixing level.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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
av_cold void swri_rematrix_free(SwrContext *s)
Definition: rematrix.c:387
int len
float rematrix_volume
rematrixing volume coefficient
float matrix[SWR_CH_MAX][SWR_CH_MAX]
floating point rematrixing coefficients
signed 16 bits, planar
Definition: samplefmt.h:58
mix_2_1_func_type * mix_2_1_f
#define AV_CH_FRONT_RIGHT
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
static int even(int64_t layout)
Definition: rematrix.c:74
#define AV_CH_SIDE_LEFT
#define FRONT_LEFT
Definition: rematrix.c:37
uint8_t matrix_ch[SWR_CH_MAX][SWR_CH_MAX+1]
Lists of input channels per output channel that have non zero rematrixing coefficients.
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel
double, planar
Definition: samplefmt.h:61
#define HAVE_MMX
Definition: config.h:48
#define AV_CH_BACK_RIGHT
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.