FFmpeg
swresample.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
3  * Copyright (c) 2002 Fabrice Bellard
4  *
5  * This file is part of libswresample
6  *
7  * libswresample is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * libswresample is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with libswresample; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/avassert.h"
24 #include "libavutil/common.h"
25 #include "libavutil/opt.h"
26 
28 
29 #undef time
30 #include <time.h>
31 #undef fprintf
32 
33 #define SAMPLES 1000
34 
35 #define SWR_CH_MAX 32
36 
37 #define ASSERT_LEVEL 2
38 
39 static double get(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f){
40  const uint8_t *p;
43  p= a[ch];
44  }else{
45  p= a[0];
46  index= ch + index*ch_count;
47  }
48 
49  switch(f){
50  case AV_SAMPLE_FMT_U8 : return ((const uint8_t*)p)[index]/127.0-1.0;
51  case AV_SAMPLE_FMT_S16: return ((const int16_t*)p)[index]/32767.0;
52  case AV_SAMPLE_FMT_S32: return ((const int32_t*)p)[index]/2147483647.0;
53  case AV_SAMPLE_FMT_FLT: return ((const float *)p)[index];
54  case AV_SAMPLE_FMT_DBL: return ((const double *)p)[index];
55  default: av_assert0(0);
56  }
57 }
58 
59 static void set(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f, double v){
60  uint8_t *p;
63  p= a[ch];
64  }else{
65  p= a[0];
66  index= ch + index*ch_count;
67  }
68  switch(f){
69  case AV_SAMPLE_FMT_U8 : ((uint8_t*)p)[index]= av_clip_uint8 (lrint((v+1.0)*127)); break;
70  case AV_SAMPLE_FMT_S16: ((int16_t*)p)[index]= av_clip_int16 (lrint(v*32767)); break;
71  case AV_SAMPLE_FMT_S32: ((int32_t*)p)[index]= av_clipl_int32(llrint(v*2147483647)); break;
72  case AV_SAMPLE_FMT_FLT: ((float *)p)[index]= v; break;
73  case AV_SAMPLE_FMT_DBL: ((double *)p)[index]= v; break;
74  default: av_assert2(0);
75  }
76 }
77 
78 static void shift(uint8_t *a[], int index, int ch_count, enum AVSampleFormat f){
79  int ch;
80 
82  f= av_get_alt_sample_fmt(f, 0);
83  for(ch= 0; ch<ch_count; ch++)
84  a[ch] += index*av_get_bytes_per_sample(f);
85  }else{
86  a[0] += index*ch_count*av_get_bytes_per_sample(f);
87  }
88 }
89 
90 static const enum AVSampleFormat formats[] = {
101 };
102 
103 static const int rates[] = {
104  8000,
105  11025,
106  16000,
107  22050,
108  32000,
109  48000,
110 };
111 
112 static const uint64_t layouts[]={
127 };
128 
130  if(av_sample_fmt_is_planar(format)){
131  int i;
132  int plane_size= av_get_bytes_per_sample(format&0xFF)*samples;
133  format&=0xFF;
134  for(i=0; i<SWR_CH_MAX; i++){
135  out[i]= in + i*plane_size;
136  }
137  }else{
138  out[0]= in;
139  }
140 }
141 
142 static int cmp(const void *a, const void *b){
143  return *(const int *)a - *(const int *)b;
144 }
145 
146 static void audiogen(void *data, enum AVSampleFormat sample_fmt,
147  int channels, int sample_rate, int nb_samples)
148 {
149  int i, ch, k;
150  double v, f, a, ampa;
151  double tabf1[SWR_CH_MAX];
152  double tabf2[SWR_CH_MAX];
153  double taba[SWR_CH_MAX];
154  unsigned static rnd;
155 
156 #define PUT_SAMPLE set(data, ch, k, channels, sample_fmt, v);
157 #define uint_rand(x) ((x) = (x) * 1664525 + 1013904223)
158 #define dbl_rand(x) (uint_rand(x)*2.0 / (double)UINT_MAX - 1)
159  k = 0;
160 
161  /* 1 second of single freq sinus at 1000 Hz */
162  a = 0;
163  for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
164  v = sin(a) * 0.30;
165  for (ch = 0; ch < channels; ch++)
166  PUT_SAMPLE
167  a += M_PI * 1000.0 * 2.0 / sample_rate;
168  }
169 
170  /* 1 second of varying frequency between 100 and 10000 Hz */
171  a = 0;
172  for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
173  v = sin(a) * 0.30;
174  for (ch = 0; ch < channels; ch++)
175  PUT_SAMPLE
176  f = 100.0 + (((10000.0 - 100.0) * i) / sample_rate);
177  a += M_PI * f * 2.0 / sample_rate;
178  }
179 
180  /* 0.5 second of low amplitude white noise */
181  for (i = 0; i < sample_rate / 2 && k < nb_samples; i++, k++) {
182  v = dbl_rand(rnd) * 0.30;
183  for (ch = 0; ch < channels; ch++)
184  PUT_SAMPLE
185  }
186 
187  /* 0.5 second of high amplitude white noise */
188  for (i = 0; i < sample_rate / 2 && k < nb_samples; i++, k++) {
189  v = dbl_rand(rnd);
190  for (ch = 0; ch < channels; ch++)
191  PUT_SAMPLE
192  }
193 
194  /* 1 second of unrelated ramps for each channel */
195  for (ch = 0; ch < channels; ch++) {
196  taba[ch] = 0;
197  tabf1[ch] = 100 + uint_rand(rnd) % 5000;
198  tabf2[ch] = 100 + uint_rand(rnd) % 5000;
199  }
200  for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
201  for (ch = 0; ch < channels; ch++) {
202  v = sin(taba[ch]) * 0.30;
203  PUT_SAMPLE
204  f = tabf1[ch] + (((tabf2[ch] - tabf1[ch]) * i) / sample_rate);
205  taba[ch] += M_PI * f * 2.0 / sample_rate;
206  }
207  }
208 
209  /* 2 seconds of 500 Hz with varying volume */
210  a = 0;
211  ampa = 0;
212  for (i = 0; i < 2 * sample_rate && k < nb_samples; i++, k++) {
213  for (ch = 0; ch < channels; ch++) {
214  double amp = (1.0 + sin(ampa)) * 0.15;
215  if (ch & 1)
216  amp = 0.30 - amp;
217  v = sin(a) * amp;
218  PUT_SAMPLE
219  a += M_PI * 500.0 * 2.0 / sample_rate;
220  ampa += M_PI * 2.0 / sample_rate;
221  }
222  }
223 }
224 
225 int main(int argc, char **argv){
226  int in_sample_rate, out_sample_rate, ch ,i, flush_count;
227  uint64_t in_ch_layout, out_ch_layout;
229  uint8_t array_in[SAMPLES*8*8];
230  uint8_t array_mid[SAMPLES*8*8*3];
231  uint8_t array_out[SAMPLES*8*8+100];
232  uint8_t *ain[SWR_CH_MAX];
233  uint8_t *aout[SWR_CH_MAX];
234  uint8_t *amid[SWR_CH_MAX];
235  int flush_i=0;
236  int mode;
237  int num_tests = 10000;
238  uint32_t seed = 0;
239  uint32_t rand_seed = 0;
241  int max_tests = FF_ARRAY_ELEMS(remaining_tests);
242  int test;
243  int specific_test= -1;
244 
245  struct SwrContext * forw_ctx= NULL;
246  struct SwrContext *backw_ctx= NULL;
247 
248  if (argc > 1) {
249  if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
250  av_log(NULL, AV_LOG_INFO, "Usage: swresample-test [<num_tests>[ <test>]] \n"
251  "num_tests Default is %d\n", num_tests);
252  return 0;
253  }
254  num_tests = strtol(argv[1], NULL, 0);
255  if(num_tests < 0) {
256  num_tests = -num_tests;
257  rand_seed = time(0);
258  }
259  if(num_tests<= 0 || num_tests>max_tests)
260  num_tests = max_tests;
261  if(argc > 2) {
262  specific_test = strtol(argv[1], NULL, 0);
263  }
264  }
265 
266  for(i=0; i<max_tests; i++)
267  remaining_tests[i] = i;
268 
269  for(test=0; test<num_tests; test++){
270  unsigned r;
271  uint_rand(seed);
272  r = (seed * (uint64_t)(max_tests - test)) >>32;
273  FFSWAP(int, remaining_tests[r], remaining_tests[max_tests - test - 1]);
274  }
275  qsort(remaining_tests + max_tests - num_tests, num_tests, sizeof(remaining_tests[0]), cmp);
276  in_sample_rate=16000;
277  for(test=0; test<num_tests; test++){
278  char in_layout_string[256];
279  char out_layout_string[256];
280  unsigned vector= remaining_tests[max_tests - test - 1];
281  int in_ch_count;
282  int out_count, mid_count, out_ch_count;
283 
284  in_ch_layout = layouts[vector % FF_ARRAY_ELEMS(layouts)]; vector /= FF_ARRAY_ELEMS(layouts);
285  out_ch_layout = layouts[vector % FF_ARRAY_ELEMS(layouts)]; vector /= FF_ARRAY_ELEMS(layouts);
286  in_sample_fmt = formats[vector % FF_ARRAY_ELEMS(formats)]; vector /= FF_ARRAY_ELEMS(formats);
287  out_sample_fmt = formats[vector % FF_ARRAY_ELEMS(formats)]; vector /= FF_ARRAY_ELEMS(formats);
288  out_sample_rate = rates [vector % FF_ARRAY_ELEMS(rates )]; vector /= FF_ARRAY_ELEMS(rates);
289  av_assert0(!vector);
290 
291  if(specific_test == 0){
292  if(out_sample_rate != in_sample_rate || in_ch_layout != out_ch_layout)
293  continue;
294  }
295 
296  in_ch_count= av_get_channel_layout_nb_channels(in_ch_layout);
297  out_ch_count= av_get_channel_layout_nb_channels(out_ch_layout);
298  av_get_channel_layout_string( in_layout_string, sizeof( in_layout_string), in_ch_count, in_ch_layout);
299  av_get_channel_layout_string(out_layout_string, sizeof(out_layout_string), out_ch_count, out_ch_layout);
300  fprintf(stderr, "TEST: %s->%s, rate:%5d->%5d, fmt:%s->%s\n",
301  in_layout_string, out_layout_string,
302  in_sample_rate, out_sample_rate,
303  av_get_sample_fmt_name(in_sample_fmt), av_get_sample_fmt_name(out_sample_fmt));
304  forw_ctx = swr_alloc_set_opts(forw_ctx, out_ch_layout, out_sample_fmt, out_sample_rate,
305  in_ch_layout, in_sample_fmt, in_sample_rate,
306  0, 0);
307  backw_ctx = swr_alloc_set_opts(backw_ctx, in_ch_layout, in_sample_fmt, in_sample_rate,
308  out_ch_layout, out_sample_fmt, out_sample_rate,
309  0, 0);
310  if(!forw_ctx) {
311  fprintf(stderr, "Failed to init forw_cts\n");
312  return 1;
313  }
314  if(!backw_ctx) {
315  fprintf(stderr, "Failed to init backw_ctx\n");
316  return 1;
317  }
318  if (uint_rand(rand_seed) % 3 == 0)
319  av_opt_set_int(forw_ctx, "ich", 0, 0);
320  if (uint_rand(rand_seed) % 3 == 0)
321  av_opt_set_int(forw_ctx, "och", 0, 0);
322 
323  if(swr_init( forw_ctx) < 0)
324  fprintf(stderr, "swr_init(->) failed\n");
325  if(swr_init(backw_ctx) < 0)
326  fprintf(stderr, "swr_init(<-) failed\n");
327  //FIXME test planar
328  setup_array(ain , array_in , in_sample_fmt, SAMPLES);
329  setup_array(amid, array_mid, out_sample_fmt, 3*SAMPLES);
330  setup_array(aout, array_out, in_sample_fmt , SAMPLES);
331 #if 0
332  for(ch=0; ch<in_ch_count; ch++){
333  for(i=0; i<SAMPLES; i++)
334  set(ain, ch, i, in_ch_count, in_sample_fmt, sin(i*i*3/SAMPLES));
335  }
336 #else
337  audiogen(ain, in_sample_fmt, in_ch_count, SAMPLES/6+1, SAMPLES);
338 #endif
339  mode = uint_rand(rand_seed) % 3;
340  if(mode==0 /*|| out_sample_rate == in_sample_rate*/) {
341  mid_count= swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, SAMPLES);
342  } else if(mode==1){
343  mid_count= swr_convert(forw_ctx, amid, 0, (const uint8_t **)ain, SAMPLES);
344  mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, 0);
345  } else {
346  int tmp_count;
347  mid_count= swr_convert(forw_ctx, amid, 0, (const uint8_t **)ain, 1);
348  av_assert0(mid_count==0);
349  shift(ain, 1, in_ch_count, in_sample_fmt);
350  mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, 0);
351  shift(amid, mid_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
352  mid_count+=swr_convert(forw_ctx, amid, 2, (const uint8_t **)ain, 2);
353  shift(amid, mid_count-tmp_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
354  shift(ain, 2, in_ch_count, in_sample_fmt);
355  mid_count+=swr_convert(forw_ctx, amid, 1, (const uint8_t **)ain, SAMPLES-3);
356  shift(amid, mid_count-tmp_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
357  shift(ain, -3, in_ch_count, in_sample_fmt);
358  mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, 0);
359  shift(amid, -tmp_count, out_ch_count, out_sample_fmt);
360  }
361  out_count= swr_convert(backw_ctx,aout, SAMPLES, (const uint8_t **)amid, mid_count);
362 
363  for(ch=0; ch<in_ch_count; ch++){
364  double sse, maxdiff=0;
365  double sum_a= 0;
366  double sum_b= 0;
367  double sum_aa= 0;
368  double sum_bb= 0;
369  double sum_ab= 0;
370  for(i=0; i<out_count; i++){
371  double a= get(ain , ch, i, in_ch_count, in_sample_fmt);
372  double b= get(aout, ch, i, in_ch_count, in_sample_fmt);
373  sum_a += a;
374  sum_b += b;
375  sum_aa+= a*a;
376  sum_bb+= b*b;
377  sum_ab+= a*b;
378  maxdiff= FFMAX(maxdiff, fabs(a-b));
379  }
380  sse= sum_aa + sum_bb - 2*sum_ab;
381  if(sse < 0 && sse > -0.00001) sse=0; //fix rounding error
382 
383  fprintf(stderr, "[e:%f c:%f max:%f] len:%5d\n", out_count ? sqrt(sse/out_count) : 0, sum_ab/(sqrt(sum_aa*sum_bb)), maxdiff, out_count);
384  }
385 
386  flush_i++;
387  flush_i%=21;
388  flush_count = swr_convert(backw_ctx,aout, flush_i, 0, 0);
389  shift(aout, flush_i, in_ch_count, in_sample_fmt);
390  flush_count+= swr_convert(backw_ctx,aout, SAMPLES-flush_i, 0, 0);
391  shift(aout, -flush_i, in_ch_count, in_sample_fmt);
392  if(flush_count){
393  for(ch=0; ch<in_ch_count; ch++){
394  double sse, maxdiff=0;
395  double sum_a= 0;
396  double sum_b= 0;
397  double sum_aa= 0;
398  double sum_bb= 0;
399  double sum_ab= 0;
400  for(i=0; i<flush_count; i++){
401  double a= get(ain , ch, i+out_count, in_ch_count, in_sample_fmt);
402  double b= get(aout, ch, i, in_ch_count, in_sample_fmt);
403  sum_a += a;
404  sum_b += b;
405  sum_aa+= a*a;
406  sum_bb+= b*b;
407  sum_ab+= a*b;
408  maxdiff= FFMAX(maxdiff, fabs(a-b));
409  }
410  sse= sum_aa + sum_bb - 2*sum_ab;
411  if(sse < 0 && sse > -0.00001) sse=0; //fix rounding error
412 
413  fprintf(stderr, "[e:%f c:%f max:%f] len:%5d F:%3d\n", sqrt(sse/flush_count), sum_ab/(sqrt(sum_aa*sum_bb)), maxdiff, flush_count, flush_i);
414  }
415  }
416 
417 
418  fprintf(stderr, "\n");
419  }
420 
421  return 0;
422 }
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
#define AV_CH_LAYOUT_7POINT1
int out_sample_rate
output sample rate
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
#define AV_CH_LAYOUT_SURROUND
#define PUT_SAMPLE
channels
Definition: aptx.c:30
double, planar
Definition: samplefmt.h:70
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
static int sse(MpegEncContext *s, uint8_t *src1, uint8_t *src2, int w, int h, int stride)
#define AV_CH_LAYOUT_4POINT0
#define AV_CH_LAYOUT_7POINT0
#define AV_CH_LAYOUT_STEREO
static void shift(uint8_t *a[], int index, int ch_count, enum AVSampleFormat f)
Definition: swresample.c:78
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 format(the sample packing is implied by the sample format) and sample rate.The lists are not just lists
#define AV_CH_LAYOUT_5POINT0
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
AV_SAMPLE_FMT_U8
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
AVOptions.
static void sum_a(const int *input, int *output, int len)
Definition: dcadct.c:26
#define f(width, name)
Definition: cbs_vp9.c:255
static const uint64_t layouts[]
Definition: swresample.c:112
enum AVSampleFormat out_sample_fmt
output sample format
signed 32 bits
Definition: samplefmt.h:62
#define av_log(a,...)
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:112
#define AV_CH_LAYOUT_5POINT1
libswresample public header
static void sum_b(const int *input, int *output, int len)
Definition: dcadct.c:34
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
The libswresample context.
const char * r
Definition: vf_curves.c:114
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:568
simple assert() macros that are a bit more flexible than ISO C assert().
#define AV_CH_LAYOUT_QUAD
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition: samplefmt.c:49
int main(int argc, char **argv)
Definition: swresample.c:225
#define FFMAX(a, b)
Definition: common.h:94
#define AV_CH_LAYOUT_2_1
#define AV_CH_LAYOUT_2_2
#define b
Definition: input.c:41
audio channel layout utility functions
signed 32 bits, planar
Definition: samplefmt.h:68
int32_t
int64_t out_ch_layout
output channel layout
struct SwrContext * swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx)
Allocate SwrContext if needed and set/reset common parameters.
Definition: swresample.c:59
int in_sample_rate
input sample rate
unsigned 8 bits, planar
Definition: samplefmt.h:66
#define SWR_CH_MAX
Definition: swresample.c:35
#define AV_CH_LAYOUT_5POINT1_BACK
#define FF_ARRAY_ELEMS(a)
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.
sample_rate
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
#define SAMPLES
Definition: swresample.c:33
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
static void test(const char *pattern, const char *host)
Definition: noproxy.c:23
static unsigned int seed
Definition: videogen.c:78
#define llrint(x)
Definition: libm.h:394
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=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);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_AARCH64) ff_audio_convert_init_aarch64(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_log(ac->avr, AV_LOG_TRACE,"%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-> in
int index
Definition: gxfenc.c:89
#define AV_CH_LAYOUT_5POINT0_BACK
enum AVSampleFormat in_sample_fmt
input sample format
int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count, const uint8_t *in_arg[SWR_CH_MAX], int in_count)
Definition: swresample.c:714
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi-0x80U))<< 56) 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_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) 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_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) 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_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) 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_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) 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)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63)))#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_S64, 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_S64, 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_S64, 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_S64, 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), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};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_X86ASM &&1) 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);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(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:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){int planes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
static const int rates[]
Definition: swresample.c:103
#define AV_CH_LAYOUT_7POINT1_WIDE
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar)
Return the planar<->packed alternative form of the given sample format, or AV_SAMPLE_FMT_NONE on erro...
Definition: samplefmt.c:66
int64_t in_ch_layout
input channel layout
common internal and external API header
#define uint_rand(x)
#define dbl_rand(x)
signed 16 bits
Definition: samplefmt.h:61
#define rnd()
Definition: checkasm.h:106
static void audiogen(void *data, enum AVSampleFormat sample_fmt, int channels, int sample_rate, int nb_samples)
Definition: swresample.c:146
static void setup_array(uint8_t *out[SWR_CH_MAX], uint8_t *in, enum AVSampleFormat format, int samples)
Definition: swresample.c:129
#define lrint
Definition: tablegen.h:53
static int cmp(const void *a, const void *b)
Definition: swresample.c:142
FILE * out
Definition: movenc.c:54
Filter the word “frame” indicates either a video frame or a group of audio samples
signed 16 bits, planar
Definition: samplefmt.h:67
#define M_PI
Definition: mathematics.h:52
formats
Definition: signature.h:48
#define FFSWAP(type, a, b)
Definition: common.h:99
#define AV_CH_LAYOUT_MONO
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:152