FFmpeg
swresample.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011-2013 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 "libavutil/opt.h"
22 #include "swresample_internal.h"
23 #include "audioconvert.h"
24 #include "libavutil/avassert.h"
26 #include "libavutil/internal.h"
27 
28 #include <float.h>
29 
30 #define ALIGN 32
31 
32 #include "libavutil/ffversion.h"
33 const char swr_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
34 
35 unsigned swresample_version(void)
36 {
39 }
40 
41 const char *swresample_configuration(void)
42 {
43  return FFMPEG_CONFIGURATION;
44 }
45 
46 const char *swresample_license(void)
47 {
48 #define LICENSE_PREFIX "libswresample license: "
49  return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
50 }
51 
52 int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){
53  if(!s || s->in_convert) // s needs to be allocated but not initialized
54  return AVERROR(EINVAL);
55  s->channel_map = channel_map;
56  return 0;
57 }
58 
62  int log_offset, void *log_ctx){
63  if(!s) s= swr_alloc();
64  if(!s) return NULL;
65 
66  s->log_level_offset= log_offset;
67  s->log_ctx= log_ctx;
68 
69  if (av_opt_set_int(s, "ocl", out_ch_layout, 0) < 0)
70  goto fail;
71 
72  if (av_opt_set_int(s, "osf", out_sample_fmt, 0) < 0)
73  goto fail;
74 
75  if (av_opt_set_int(s, "osr", out_sample_rate, 0) < 0)
76  goto fail;
77 
78  if (av_opt_set_int(s, "icl", in_ch_layout, 0) < 0)
79  goto fail;
80 
81  if (av_opt_set_int(s, "isf", in_sample_fmt, 0) < 0)
82  goto fail;
83 
84  if (av_opt_set_int(s, "isr", in_sample_rate, 0) < 0)
85  goto fail;
86 
88  goto fail;
89 
90  if (av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->user_out_ch_layout), 0) < 0)
91  goto fail;
92 
93  av_opt_set_int(s, "uch", 0, 0);
94  return s;
95 fail:
96  av_log(s, AV_LOG_ERROR, "Failed to set option\n");
97  swr_free(&s);
98  return NULL;
99 }
100 
102  a->fmt = fmt;
103  a->bps = av_get_bytes_per_sample(fmt);
104  a->planar= av_sample_fmt_is_planar(fmt);
105  if (a->ch_count == 1)
106  a->planar = 1;
107 }
108 
109 static void free_temp(AudioData *a){
110  av_free(a->data);
111  memset(a, 0, sizeof(*a));
112 }
113 
114 static void clear_context(SwrContext *s){
115  s->in_buffer_index= 0;
116  s->in_buffer_count= 0;
117  s->resample_in_constraint= 0;
118  memset(s->in.ch, 0, sizeof(s->in.ch));
119  memset(s->out.ch, 0, sizeof(s->out.ch));
120  free_temp(&s->postin);
121  free_temp(&s->midbuf);
122  free_temp(&s->preout);
123  free_temp(&s->in_buffer);
124  free_temp(&s->silence);
125  free_temp(&s->drop_temp);
126  free_temp(&s->dither.noise);
127  free_temp(&s->dither.temp);
129  swri_audio_convert_free(&s->out_convert);
130  swri_audio_convert_free(&s->full_convert);
132 
133  s->delayed_samples_fixup = 0;
134  s->flushed = 0;
135 }
136 
138  SwrContext *s= *ss;
139  if(s){
140  clear_context(s);
141  if (s->resampler)
142  s->resampler->free(&s->resample);
143  }
144 
145  av_freep(ss);
146 }
147 
149  clear_context(s);
150 }
151 
153  int ret;
154  char l1[1024], l2[1024];
155 
156  clear_context(s);
157 
159  av_log(s, AV_LOG_ERROR, "Requested input sample format %d is invalid\n", s->in_sample_fmt);
160  return AVERROR(EINVAL);
161  }
162  if(s->out_sample_fmt >= AV_SAMPLE_FMT_NB){
163  av_log(s, AV_LOG_ERROR, "Requested output sample format %d is invalid\n", s->out_sample_fmt);
164  return AVERROR(EINVAL);
165  }
166 
167  if(s-> in_sample_rate <= 0){
168  av_log(s, AV_LOG_ERROR, "Requested input sample rate %d is invalid\n", s->in_sample_rate);
169  return AVERROR(EINVAL);
170  }
171  if(s->out_sample_rate <= 0){
172  av_log(s, AV_LOG_ERROR, "Requested output sample rate %d is invalid\n", s->out_sample_rate);
173  return AVERROR(EINVAL);
174  }
175  s->out.ch_count = s-> user_out_ch_count;
176  s-> in.ch_count = s-> user_in_ch_count;
177  s->used_ch_count = s->user_used_ch_count;
178 
180  s->out_ch_layout = s->user_out_ch_layout;
181 
182  s->int_sample_fmt= s->user_int_sample_fmt;
183 
184  s->dither.method = s->user_dither_method;
185 
187  av_log(s, AV_LOG_WARNING, "Input channel layout 0x%"PRIx64" is invalid or unsupported.\n", s-> in_ch_layout);
188  s->in_ch_layout = 0;
189  }
190 
191  if(av_get_channel_layout_nb_channels(s->out_ch_layout) > SWR_CH_MAX) {
192  av_log(s, AV_LOG_WARNING, "Output channel layout 0x%"PRIx64" is invalid or unsupported.\n", s->out_ch_layout);
193  s->out_ch_layout = 0;
194  }
195 
196  switch(s->engine){
197 #if CONFIG_LIBSOXR
198  case SWR_ENGINE_SOXR: s->resampler = &swri_soxr_resampler; break;
199 #endif
200  case SWR_ENGINE_SWR : s->resampler = &swri_resampler; break;
201  default:
202  av_log(s, AV_LOG_ERROR, "Requested resampling engine is unavailable\n");
203  return AVERROR(EINVAL);
204  }
205 
206  if(!s->used_ch_count)
207  s->used_ch_count= s->in.ch_count;
208 
209  if(s->used_ch_count && s-> in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s-> in_ch_layout)){
210  av_log(s, AV_LOG_WARNING, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
211  s-> in_ch_layout= 0;
212  }
213 
214  if(!s-> in_ch_layout)
215  s-> in_ch_layout= av_get_default_channel_layout(s->used_ch_count);
216  if(!s->out_ch_layout)
217  s->out_ch_layout= av_get_default_channel_layout(s->out.ch_count);
218 
219  s->rematrix= s->out_ch_layout !=s->in_ch_layout || s->rematrix_volume!=1.0 ||
220  s->rematrix_custom;
221 
222  if(s->int_sample_fmt == AV_SAMPLE_FMT_NONE){
224  && av_get_bytes_per_sample(s->out_sample_fmt) <= 2){
225  s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
226  }else if( av_get_bytes_per_sample(s-> in_sample_fmt) <= 2
227  && !s->rematrix
228  && s->out_sample_rate==s->in_sample_rate
229  && !(s->flags & SWR_FLAG_RESAMPLE)){
230  s->int_sample_fmt= AV_SAMPLE_FMT_S16P;
232  && av_get_planar_sample_fmt(s->out_sample_fmt) == AV_SAMPLE_FMT_S32P
233  && !s->rematrix
234  && s->out_sample_rate == s->in_sample_rate
235  && !(s->flags & SWR_FLAG_RESAMPLE)
236  && s->engine != SWR_ENGINE_SOXR){
237  s->int_sample_fmt= AV_SAMPLE_FMT_S32P;
238  }else if(av_get_bytes_per_sample(s->in_sample_fmt) <= 4){
239  s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;
240  }else{
241  s->int_sample_fmt= AV_SAMPLE_FMT_DBLP;
242  }
243  }
244  av_log(s, AV_LOG_DEBUG, "Using %s internally between filters\n", av_get_sample_fmt_name(s->int_sample_fmt));
245 
246  if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P
247  &&s->int_sample_fmt != AV_SAMPLE_FMT_S32P
248  &&s->int_sample_fmt != AV_SAMPLE_FMT_S64P
249  &&s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
250  &&s->int_sample_fmt != AV_SAMPLE_FMT_DBLP){
251  av_log(s, AV_LOG_ERROR, "Requested sample format %s is not supported internally, s16p/s32p/s64p/fltp/dblp are supported\n", av_get_sample_fmt_name(s->int_sample_fmt));
252  return AVERROR(EINVAL);
253  }
254 
256  set_audiodata_fmt(&s->out, s->out_sample_fmt);
257 
258  if (s->firstpts_in_samples != AV_NOPTS_VALUE) {
259  if (!s->async && s->min_compensation >= FLT_MAX/2)
260  s->async = 1;
261  s->firstpts =
262  s->outpts = s->firstpts_in_samples * s->out_sample_rate;
263  } else
264  s->firstpts = AV_NOPTS_VALUE;
265 
266  if (s->async) {
267  if (s->min_compensation >= FLT_MAX/2)
268  s->min_compensation = 0.001;
269  if (s->async > 1.0001) {
270  s->max_soft_compensation = s->async / (double) s->in_sample_rate;
271  }
272  }
273 
274  if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){
275  s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby, s->exact_rational);
276  if (!s->resample) {
277  av_log(s, AV_LOG_ERROR, "Failed to initialize resampler\n");
278  return AVERROR(ENOMEM);
279  }
280  }else
281  s->resampler->free(&s->resample);
282  if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P
283  && s->int_sample_fmt != AV_SAMPLE_FMT_S32P
284  && s->int_sample_fmt != AV_SAMPLE_FMT_FLTP
285  && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP
286  && s->resample){
287  av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16p/s32p/fltp/dblp\n");
288  ret = AVERROR(EINVAL);
289  goto fail;
290  }
291 
292 #define RSC 1 //FIXME finetune
293  if(!s-> in.ch_count)
295  if(!s->used_ch_count)
296  s->used_ch_count= s->in.ch_count;
297  if(!s->out.ch_count)
298  s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout);
299 
300  if(!s-> in.ch_count){
301  av_assert0(!s->in_ch_layout);
302  av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n");
303  ret = AVERROR(EINVAL);
304  goto fail;
305  }
306 
307  av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> in_ch_layout);
308  av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, s->out_ch_layout);
309  if (s->out_ch_layout && s->out.ch_count != av_get_channel_layout_nb_channels(s->out_ch_layout)) {
310  av_log(s, AV_LOG_ERROR, "Output channel layout %s mismatches specified channel count %d\n", l2, s->out.ch_count);
311  ret = AVERROR(EINVAL);
312  goto fail;
313  }
314  if (s->in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s->in_ch_layout)) {
315  av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_count);
316  ret = AVERROR(EINVAL);
317  goto fail;
318  }
319 
320  if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != s->out.ch_count && !s->rematrix_custom) {
321  av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s "
322  "but there is not enough information to do it\n", l1, l2);
323  ret = AVERROR(EINVAL);
324  goto fail;
325  }
326 
327 av_assert0(s->used_ch_count);
328 av_assert0(s->out.ch_count);
329  s->resample_first= RSC*s->out.ch_count/s->used_ch_count - RSC < s->out_sample_rate/(float)s-> in_sample_rate - 1.0;
330 
331  s->in_buffer= s->in;
332  s->silence = s->in;
333  s->drop_temp= s->out;
334 
335  if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0)
336  goto fail;
337 
338  if(!s->resample && !s->rematrix && !s->channel_map && !s->dither.method){
339  s->full_convert = swri_audio_convert_alloc(s->out_sample_fmt,
340  s-> in_sample_fmt, s-> in.ch_count, NULL, 0);
341  return 0;
342  }
343 
344  s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt,
345  s-> in_sample_fmt, s->used_ch_count, s->channel_map, 0);
346  s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
347  s->int_sample_fmt, s->out.ch_count, NULL, 0);
348 
349  if (!s->in_convert || !s->out_convert) {
350  ret = AVERROR(ENOMEM);
351  goto fail;
352  }
353 
354  s->postin= s->in;
355  s->preout= s->out;
356  s->midbuf= s->in;
357 
358  if(s->channel_map){
359  s->postin.ch_count=
360  s->midbuf.ch_count= s->used_ch_count;
361  if(s->resample)
362  s->in_buffer.ch_count= s->used_ch_count;
363  }
364  if(!s->resample_first){
365  s->midbuf.ch_count= s->out.ch_count;
366  if(s->resample)
367  s->in_buffer.ch_count = s->out.ch_count;
368  }
369 
370  set_audiodata_fmt(&s->postin, s->int_sample_fmt);
371  set_audiodata_fmt(&s->midbuf, s->int_sample_fmt);
372  set_audiodata_fmt(&s->preout, s->int_sample_fmt);
373 
374  if(s->resample){
375  set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
376  }
377 
378  av_assert0(!s->preout.count);
379  s->dither.noise = s->preout;
380  s->dither.temp = s->preout;
381  if (s->dither.method > SWR_DITHER_NS) {
382  s->dither.noise.bps = 4;
383  s->dither.noise.fmt = AV_SAMPLE_FMT_FLTP;
384  s->dither.noise_scale = 1;
385  }
386 
387  if(s->rematrix || s->dither.method) {
389  if (ret < 0)
390  goto fail;
391  }
392 
393  return 0;
394 fail:
395  swr_close(s);
396  return ret;
397 
398 }
399 
401  int i, countb;
402  AudioData old;
403 
404  if(count < 0 || count > INT_MAX/2/a->bps/a->ch_count)
405  return AVERROR(EINVAL);
406 
407  if(a->count >= count)
408  return 0;
409 
410  count*=2;
411 
412  countb= FFALIGN(count*a->bps, ALIGN);
413  old= *a;
414 
415  av_assert0(a->bps);
416  av_assert0(a->ch_count);
417 
418  a->data= av_mallocz_array(countb, a->ch_count);
419  if(!a->data)
420  return AVERROR(ENOMEM);
421  for(i=0; i<a->ch_count; i++){
422  a->ch[i]= a->data + i*(a->planar ? countb : a->bps);
423  if(a->count && a->planar) memcpy(a->ch[i], old.ch[i], a->count*a->bps);
424  }
425  if(a->count && !a->planar) memcpy(a->ch[0], old.ch[0], a->count*a->ch_count*a->bps);
426  av_freep(&old.data);
427  a->count= count;
428 
429  return 1;
430 }
431 
432 static void copy(AudioData *out, AudioData *in,
433  int count){
434  av_assert0(out->planar == in->planar);
435  av_assert0(out->bps == in->bps);
436  av_assert0(out->ch_count == in->ch_count);
437  if(out->planar){
438  int ch;
439  for(ch=0; ch<out->ch_count; ch++)
440  memcpy(out->ch[ch], in->ch[ch], count*out->bps);
441  }else
442  memcpy(out->ch[0], in->ch[0], count*out->ch_count*out->bps);
443 }
444 
445 static void fill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
446  int i;
447  if(!in_arg){
448  memset(out->ch, 0, sizeof(out->ch));
449  }else if(out->planar){
450  for(i=0; i<out->ch_count; i++)
451  out->ch[i]= in_arg[i];
452  }else{
453  for(i=0; i<out->ch_count; i++)
454  out->ch[i]= in_arg[0] + i*out->bps;
455  }
456 }
457 
459  int i;
460  if(out->planar){
461  for(i=0; i<out->ch_count; i++)
462  in_arg[i]= out->ch[i];
463  }else{
464  in_arg[0]= out->ch[0];
465  }
466 }
467 
468 /**
469  *
470  * out may be equal in.
471  */
472 static void buf_set(AudioData *out, AudioData *in, int count){
473  int ch;
474  if(in->planar){
475  for(ch=0; ch<out->ch_count; ch++)
476  out->ch[ch]= in->ch[ch] + count*out->bps;
477  }else{
478  for(ch=out->ch_count-1; ch>=0; ch--)
479  out->ch[ch]= in->ch[0] + (ch + count*out->ch_count) * out->bps;
480  }
481 }
482 
483 /**
484  *
485  * @return number of samples output per channel
486  */
487 static int resample(SwrContext *s, AudioData *out_param, int out_count,
488  const AudioData * in_param, int in_count){
489  AudioData in, out, tmp;
490  int ret_sum=0;
491  int border=0;
492  int padless = ARCH_X86 && s->engine == SWR_ENGINE_SWR ? 7 : 0;
493 
494  av_assert1(s->in_buffer.ch_count == in_param->ch_count);
495  av_assert1(s->in_buffer.planar == in_param->planar);
496  av_assert1(s->in_buffer.fmt == in_param->fmt);
497 
498  tmp=out=*out_param;
499  in = *in_param;
500 
501  border = s->resampler->invert_initial_buffer(s->resample, &s->in_buffer,
502  &in, in_count, &s->in_buffer_index, &s->in_buffer_count);
503  if (border == INT_MAX) {
504  return 0;
505  } else if (border < 0) {
506  return border;
507  } else if (border) {
508  buf_set(&in, &in, border);
509  in_count -= border;
510  s->resample_in_constraint = 0;
511  }
512 
513  do{
514  int ret, size, consumed;
515  if(!s->resample_in_constraint && s->in_buffer_count){
516  buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
517  ret= s->resampler->multiple_resample(s->resample, &out, out_count, &tmp, s->in_buffer_count, &consumed);
518  out_count -= ret;
519  ret_sum += ret;
520  buf_set(&out, &out, ret);
521  s->in_buffer_count -= consumed;
522  s->in_buffer_index += consumed;
523 
524  if(!in_count)
525  break;
526  if(s->in_buffer_count <= border){
527  buf_set(&in, &in, -s->in_buffer_count);
528  in_count += s->in_buffer_count;
529  s->in_buffer_count=0;
530  s->in_buffer_index=0;
531  border = 0;
532  }
533  }
534 
535  if((s->flushed || in_count > padless) && !s->in_buffer_count){
536  s->in_buffer_index=0;
537  ret= s->resampler->multiple_resample(s->resample, &out, out_count, &in, FFMAX(in_count-padless, 0), &consumed);
538  out_count -= ret;
539  ret_sum += ret;
540  buf_set(&out, &out, ret);
541  in_count -= consumed;
542  buf_set(&in, &in, consumed);
543  }
544 
545  //TODO is this check sane considering the advanced copy avoidance below
546  size= s->in_buffer_index + s->in_buffer_count + in_count;
547  if( size > s->in_buffer.count
548  && s->in_buffer_count + in_count <= s->in_buffer_index){
549  buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
550  copy(&s->in_buffer, &tmp, s->in_buffer_count);
551  s->in_buffer_index=0;
552  }else
553  if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
554  return ret;
555 
556  if(in_count){
557  int count= in_count;
558  if(s->in_buffer_count && s->in_buffer_count+2 < count && out_count) count= s->in_buffer_count+2;
559 
560  buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
561  copy(&tmp, &in, /*in_*/count);
562  s->in_buffer_count += count;
563  in_count -= count;
564  border += count;
565  buf_set(&in, &in, count);
566  s->resample_in_constraint= 0;
567  if(s->in_buffer_count != count || in_count)
568  continue;
569  if (padless) {
570  padless = 0;
571  continue;
572  }
573  }
574  break;
575  }while(1);
576 
577  s->resample_in_constraint= !!out_count;
578 
579  return ret_sum;
580 }
581 
582 static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count,
583  AudioData *in , int in_count){
585  int ret/*, in_max*/;
586  AudioData preout_tmp, midbuf_tmp;
587 
588  if(s->full_convert){
589  av_assert0(!s->resample);
590  swri_audio_convert(s->full_convert, out, in, in_count);
591  return out_count;
592  }
593 
594 // in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
595 // in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
596 
597  if((ret=swri_realloc_audio(&s->postin, in_count))<0)
598  return ret;
599  if(s->resample_first){
600  av_assert0(s->midbuf.ch_count == s->used_ch_count);
601  if((ret=swri_realloc_audio(&s->midbuf, out_count))<0)
602  return ret;
603  }else{
604  av_assert0(s->midbuf.ch_count == s->out.ch_count);
605  if((ret=swri_realloc_audio(&s->midbuf, in_count))<0)
606  return ret;
607  }
608  if((ret=swri_realloc_audio(&s->preout, out_count))<0)
609  return ret;
610 
611  postin= &s->postin;
612 
613  midbuf_tmp= s->midbuf;
614  midbuf= &midbuf_tmp;
615  preout_tmp= s->preout;
616  preout= &preout_tmp;
617 
618  if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar && !s->channel_map)
619  postin= in;
620 
621  if(s->resample_first ? !s->resample : !s->rematrix)
622  midbuf= postin;
623 
624  if(s->resample_first ? !s->rematrix : !s->resample)
625  preout= midbuf;
626 
627  if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar
628  && !(s->out_sample_fmt==AV_SAMPLE_FMT_S32P && (s->dither.output_sample_bits&31))){
629  if(preout==in){
630  out_count= FFMIN(out_count, in_count); //TODO check at the end if this is needed or redundant
631  av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though
632  copy(out, in, out_count);
633  return out_count;
634  }
635  else if(preout==postin) preout= midbuf= postin= out;
636  else if(preout==midbuf) preout= midbuf= out;
637  else preout= out;
638  }
639 
640  if(in != postin){
641  swri_audio_convert(s->in_convert, postin, in, in_count);
642  }
643 
644  if(s->resample_first){
645  if(postin != midbuf)
646  out_count= resample(s, midbuf, out_count, postin, in_count);
647  if(midbuf != preout)
648  swri_rematrix(s, preout, midbuf, out_count, preout==out);
649  }else{
650  if(postin != midbuf)
651  swri_rematrix(s, midbuf, postin, in_count, midbuf==out);
652  if(midbuf != preout)
653  out_count= resample(s, preout, out_count, midbuf, in_count);
654  }
655 
656  if(preout != out && out_count){
657  AudioData *conv_src = preout;
658  if(s->dither.method){
659  int ch;
660  int dither_count= FFMAX(out_count, 1<<16);
661 
662  if (preout == in) {
663  conv_src = &s->dither.temp;
664  if((ret=swri_realloc_audio(&s->dither.temp, dither_count))<0)
665  return ret;
666  }
667 
668  if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0)
669  return ret;
670  if(ret)
671  for(ch=0; ch<s->dither.noise.ch_count; ch++)
672  if((ret=swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, (12345678913579ULL*ch + 3141592) % 2718281828U, s->dither.noise.fmt))<0)
673  return ret;
674  av_assert0(s->dither.noise.ch_count == preout->ch_count);
675 
676  if(s->dither.noise_pos + out_count > s->dither.noise.count)
677  s->dither.noise_pos = 0;
678 
679  if (s->dither.method < SWR_DITHER_NS){
680  if (s->mix_2_1_simd) {
681  int len1= out_count&~15;
682  int off = len1 * preout->bps;
683 
684  if(len1)
685  for(ch=0; ch<preout->ch_count; ch++)
686  s->mix_2_1_simd(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_simd_one, 0, 0, len1);
687  if(out_count != len1)
688  for(ch=0; ch<preout->ch_count; ch++)
689  s->mix_2_1_f(conv_src->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos + off, s->native_one, 0, 0, out_count - len1);
690  } else {
691  for(ch=0; ch<preout->ch_count; ch++)
692  s->mix_2_1_f(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_one, 0, 0, out_count);
693  }
694  } else {
695  switch(s->int_sample_fmt) {
696  case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, conv_src, preout, &s->dither.noise, out_count); break;
697  case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, conv_src, preout, &s->dither.noise, out_count); break;
698  case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, conv_src, preout, &s->dither.noise, out_count); break;
699  case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,conv_src, preout, &s->dither.noise, out_count); break;
700  }
701  }
702  s->dither.noise_pos += out_count;
703  }
704 //FIXME packed doesn't need more than 1 chan here!
705  swri_audio_convert(s->out_convert, out, conv_src, out_count);
706  }
707  return out_count;
708 }
709 
711  return !!s->in_buffer.ch_count;
712 }
713 
714 int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count,
715  const uint8_t *in_arg [SWR_CH_MAX], int in_count){
716  AudioData * in= &s->in;
717  AudioData *out= &s->out;
718  int av_unused max_output;
719 
720  if (!swr_is_initialized(s)) {
721  av_log(s, AV_LOG_ERROR, "Context has not been initialized\n");
722  return AVERROR(EINVAL);
723  }
724 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL >1
725  max_output = swr_get_out_samples(s, in_count);
726 #endif
727 
728  while(s->drop_output > 0){
729  int ret;
730  uint8_t *tmp_arg[SWR_CH_MAX];
731 #define MAX_DROP_STEP 16384
732  if((ret=swri_realloc_audio(&s->drop_temp, FFMIN(s->drop_output, MAX_DROP_STEP)))<0)
733  return ret;
734 
735  reversefill_audiodata(&s->drop_temp, tmp_arg);
736  s->drop_output *= -1; //FIXME find a less hackish solution
737  ret = swr_convert(s, tmp_arg, FFMIN(-s->drop_output, MAX_DROP_STEP), in_arg, in_count); //FIXME optimize but this is as good as never called so maybe it doesn't matter
738  s->drop_output *= -1;
739  in_count = 0;
740  if(ret>0) {
741  s->drop_output -= ret;
742  if (!s->drop_output && !out_arg)
743  return 0;
744  continue;
745  }
746 
747  av_assert0(s->drop_output);
748  return 0;
749  }
750 
751  if(!in_arg){
752  if(s->resample){
753  if (!s->flushed)
754  s->resampler->flush(s);
755  s->resample_in_constraint = 0;
756  s->flushed = 1;
757  }else if(!s->in_buffer_count){
758  return 0;
759  }
760  }else
761  fill_audiodata(in , (void*)in_arg);
762 
763  fill_audiodata(out, out_arg);
764 
765  if(s->resample){
766  int ret = swr_convert_internal(s, out, out_count, in, in_count);
767  if(ret>0 && !s->drop_output)
768  s->outpts += ret * (int64_t)s->in_sample_rate;
769 
770  av_assert2(max_output < 0 || ret < 0 || ret <= max_output);
771 
772  return ret;
773  }else{
774  AudioData tmp= *in;
775  int ret2=0;
776  int ret, size;
777  size = FFMIN(out_count, s->in_buffer_count);
778  if(size){
779  buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
781  if(ret<0)
782  return ret;
783  ret2= ret;
784  s->in_buffer_count -= ret;
785  s->in_buffer_index += ret;
786  buf_set(out, out, ret);
787  out_count -= ret;
788  if(!s->in_buffer_count)
789  s->in_buffer_index = 0;
790  }
791 
792  if(in_count){
793  size= s->in_buffer_index + s->in_buffer_count + in_count - out_count;
794 
795  if(in_count > out_count) { //FIXME move after swr_convert_internal
796  if( size > s->in_buffer.count
797  && s->in_buffer_count + in_count - out_count <= s->in_buffer_index){
798  buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
799  copy(&s->in_buffer, &tmp, s->in_buffer_count);
800  s->in_buffer_index=0;
801  }else
802  if((ret=swri_realloc_audio(&s->in_buffer, size)) < 0)
803  return ret;
804  }
805 
806  if(out_count){
807  size = FFMIN(in_count, out_count);
809  if(ret<0)
810  return ret;
811  buf_set(in, in, ret);
812  in_count -= ret;
813  ret2 += ret;
814  }
815  if(in_count){
816  buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
817  copy(&tmp, in, in_count);
818  s->in_buffer_count += in_count;
819  }
820  }
821  if(ret2>0 && !s->drop_output)
822  s->outpts += ret2 * (int64_t)s->in_sample_rate;
823  av_assert2(max_output < 0 || ret2 < 0 || ret2 <= max_output);
824  return ret2;
825  }
826 }
827 
828 int swr_drop_output(struct SwrContext *s, int count){
829  const uint8_t *tmp_arg[SWR_CH_MAX];
830  s->drop_output += count;
831 
832  if(s->drop_output <= 0)
833  return 0;
834 
835  av_log(s, AV_LOG_VERBOSE, "discarding %d audio samples\n", count);
836  return swr_convert(s, NULL, s->drop_output, tmp_arg, 0);
837 }
838 
840  int ret, i;
841  uint8_t *tmp_arg[SWR_CH_MAX];
842 
843  if(count <= 0)
844  return 0;
845 
846 #define MAX_SILENCE_STEP 16384
847  while (count > MAX_SILENCE_STEP) {
849  return ret;
851  }
852 
853  if((ret=swri_realloc_audio(&s->silence, count))<0)
854  return ret;
855 
856  if(s->silence.planar) for(i=0; i<s->silence.ch_count; i++) {
857  memset(s->silence.ch[i], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps);
858  } else
859  memset(s->silence.ch[0], s->silence.bps==1 ? 0x80 : 0, count*s->silence.bps*s->silence.ch_count);
860 
861  reversefill_audiodata(&s->silence, tmp_arg);
862  av_log(s, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", count);
863  ret = swr_convert(s, NULL, 0, (const uint8_t**)tmp_arg, count);
864  return ret;
865 }
866 
867 int64_t swr_get_delay(struct SwrContext *s, int64_t base){
868  if (s->resampler && s->resample){
869  return s->resampler->get_delay(s, base);
870  }else{
871  return (s->in_buffer_count*base + (s->in_sample_rate>>1))/ s->in_sample_rate;
872  }
873 }
874 
875 int swr_get_out_samples(struct SwrContext *s, int in_samples)
876 {
877  int64_t out_samples;
878 
879  if (in_samples < 0)
880  return AVERROR(EINVAL);
881 
882  if (s->resampler && s->resample) {
883  if (!s->resampler->get_out_samples)
884  return AVERROR(ENOSYS);
885  out_samples = s->resampler->get_out_samples(s, in_samples);
886  } else {
887  out_samples = s->in_buffer_count + in_samples;
888  av_assert0(s->out_sample_rate == s->in_sample_rate);
889  }
890 
891  if (out_samples > INT_MAX)
892  return AVERROR(EINVAL);
893 
894  return out_samples;
895 }
896 
897 int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance){
898  int ret;
899 
900  if (!s || compensation_distance < 0)
901  return AVERROR(EINVAL);
902  if (!compensation_distance && sample_delta)
903  return AVERROR(EINVAL);
904  if (!s->resample) {
905  s->flags |= SWR_FLAG_RESAMPLE;
906  ret = swr_init(s);
907  if (ret < 0)
908  return ret;
909  }
910  if (!s->resampler->set_compensation){
911  return AVERROR(EINVAL);
912  }else{
913  return s->resampler->set_compensation(s->resample, sample_delta, compensation_distance);
914  }
915 }
916 
917 int64_t swr_next_pts(struct SwrContext *s, int64_t pts){
918  if(pts == INT64_MIN)
919  return s->outpts;
920 
921  if (s->firstpts == AV_NOPTS_VALUE)
922  s->outpts = s->firstpts = pts;
923 
924  if(s->min_compensation >= FLT_MAX) {
925  return (s->outpts = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate));
926  } else {
927  int64_t delta = pts - swr_get_delay(s, s->in_sample_rate * (int64_t)s->out_sample_rate) - s->outpts + s->drop_output*(int64_t)s->in_sample_rate;
928  double fdelta = delta /(double)(s->in_sample_rate * (int64_t)s->out_sample_rate);
929 
930  if(fabs(fdelta) > s->min_compensation) {
931  if(s->outpts == s->firstpts || fabs(fdelta) > s->min_hard_compensation){
932  int ret;
933  if(delta > 0) ret = swr_inject_silence(s, delta / s->out_sample_rate);
934  else ret = swr_drop_output (s, -delta / s-> in_sample_rate);
935  if(ret<0){
936  av_log(s, AV_LOG_ERROR, "Failed to compensate for timestamp delta of %f\n", fdelta);
937  }
938  } else if(s->soft_compensation_duration && s->max_soft_compensation) {
939  int duration = s->out_sample_rate * s->soft_compensation_duration;
940  double max_soft_compensation = s->max_soft_compensation / (s->max_soft_compensation < 0 ? -s->in_sample_rate : 1);
941  int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) * duration ;
942  av_log(s, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
944  }
945  }
946 
947  return s->outpts;
948  }
949 }
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
swr_convert_internal
static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count, AudioData *in, int in_count)
Definition: swresample.c:582
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
SwrContext::out_ch_layout
int64_t out_ch_layout
output channel layout
Definition: swresample_internal.h:103
fill_audiodata
static void fill_audiodata(AudioData *out, uint8_t *in_arg[SWR_CH_MAX])
Definition: swresample.c:445
swri_noise_shaping_int16
void swri_noise_shaping_int16(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count)
out
FILE * out
Definition: movenc.c:54
SwrContext::in_sample_rate
int in_sample_rate
input sample rate
Definition: swresample_internal.h:104
free_temp
static void free_temp(AudioData *a)
Definition: swresample.c:109
comp
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
Definition: eamad.c:83
swr_set_compensation
int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance)
Activate resampling compensation ("soft" compensation).
Definition: swresample.c:897
ch
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/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_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 *(INT64_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 *(INT64_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
SwrContext::user_in_ch_count
int user_in_ch_count
User set input channel count.
Definition: swresample_internal.h:117
LIBSWRESAMPLE_VERSION_MICRO
#define LIBSWRESAMPLE_VERSION_MICRO
Definition: version.h:33
AudioData::bps
int bps
bytes per sample
Definition: swresample_internal.h:49
count
void INT64 INT64 count
Definition: avisynth_c.h:767
av_unused
#define av_unused
Definition: attributes.h:125
AudioData::data
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:39
av_get_channel_layout_string
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.
Definition: channel_layout.c:211
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
SwrContext::out_sample_rate
int out_sample_rate
output sample rate
Definition: swresample_internal.h:105
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:68
swri_resampler
struct Resampler const swri_resampler
Definition: resample.c:613
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
base
uint8_t base
Definition: vp3data.h:202
float.h
swr_set_channel_mapping
int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map)
Set a customized input channel mapping.
Definition: swresample.c:52
copy
static void copy(AudioData *out, AudioData *in, int count)
Definition: swresample.c:432
SwrContext::in_buffer_index
int in_buffer_index
cached buffer position
Definition: swresample_internal.h:156
swri_noise_shaping_float
void swri_noise_shaping_float(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count)
SWR_ENGINE_SOXR
@ SWR_ENGINE_SOXR
SoX Resampler.
Definition: swresample.h:161
buf_set
static void buf_set(AudioData *out, AudioData *in, int count)
out may be equal in.
Definition: swresample.c:472
AudioData
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
fmt
const char * fmt
Definition: avisynth_c.h:861
U
#define U(x)
Definition: vp56_arith.h:37
SwrContext::out_sample_fmt
enum AVSampleFormat out_sample_fmt
output sample format
Definition: swresample_internal.h:101
fail
#define fail()
Definition: checkasm.h:120
swri_realloc_audio
int swri_realloc_audio(AudioData *a, int count)
Definition: swresample.c:400
MAX_SILENCE_STEP
#define MAX_SILENCE_STEP
swr_is_initialized
int swr_is_initialized(struct SwrContext *s)
Check whether an swr context has been initialized or not.
Definition: swresample.c:710
AV_SAMPLE_FMT_S64P
@ AV_SAMPLE_FMT_S64P
signed 64 bits, planar
Definition: samplefmt.h:72
pts
static int64_t pts
Definition: transcode_aac.c:647
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:261
swr_next_pts
int64_t swr_next_pts(struct SwrContext *s, int64_t pts)
Convert the next timestamp from input to output timestamps are in 1/(in_sample_rate * out_sample_rate...
Definition: swresample.c:917
swr_get_delay
int64_t swr_get_delay(struct SwrContext *s, int64_t base)
Gets the delay the next input sample will experience relative to the next output sample.
Definition: swresample.c:867
av_get_planar_sample_fmt
enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt)
Get the planar alternative form of the given sample format.
Definition: samplefmt.c:84
SwrContext::postin
AudioData postin
post-input audio data: used for rematrix/resample
Definition: swresample_internal.h:149
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:84
swr_inject_silence
int swr_inject_silence(struct SwrContext *s, int count)
Injects the specified number of silence samples.
Definition: swresample.c:839
swr_init
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.
Definition: swresample.c:152
duration
int64_t duration
Definition: movenc.c:63
s
#define s(width, name)
Definition: cbs_vp9.c:257
swr_alloc
av_cold struct SwrContext * swr_alloc(void)
Allocate SwrContext.
Definition: options.c:149
SwrContext::user_out_ch_count
int user_out_ch_count
User set output channel count.
Definition: swresample_internal.h:118
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
av_sample_fmt_is_planar
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:112
swri_rematrix
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy)
Definition: rematrix.c:497
SWR_DITHER_NS
@ SWR_DITHER_NS
not part of API/ABI
Definition: swresample.h:147
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
swr_convert
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
AudioData::planar
int planar
1 if planar audio, 0 otherwise
Definition: swresample_internal.h:51
SwrContext::in_convert
struct AudioConvert * in_convert
input conversion context
Definition: swresample_internal.h:165
swri_audio_convert
int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len)
Convert between audio sample formats.
av_get_sample_fmt_name
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
SwrContext
The libswresample context.
Definition: swresample_internal.h:95
swr_alloc_set_opts
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
AudioData::ch
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel
Definition: swresample_internal.h:46
if
if(ret)
Definition: filter_design.txt:179
swri_noise_shaping_int32
void swri_noise_shaping_int32(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count)
SwrContext::midbuf
AudioData midbuf
intermediate audio data (postin/preout)
Definition: swresample_internal.h:150
NULL
#define NULL
Definition: coverity.c:32
reversefill_audiodata
static void reversefill_audiodata(AudioData *out, uint8_t *in_arg[SWR_CH_MAX])
Definition: swresample.c:458
swresample_license
const char * swresample_license(void)
Return the swr license.
Definition: swresample.c:46
SwrContext::log_ctx
void * log_ctx
parent logging context
Definition: swresample_internal.h:98
resample
static int resample(SwrContext *s, AudioData *out_param, int out_count, const AudioData *in_param, int in_count)
Definition: swresample.c:487
swri_soxr_resampler
struct Resampler const swri_soxr_resampler
Definition: soxr_resample.c:126
ALIGN
#define ALIGN
Definition: swresample.c:30
av_get_channel_layout_nb_channels
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
Definition: channel_layout.c:220
av_opt_set_int
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
Definition: opt.c:568
AudioData::ch_count
int ch_count
number of channels
Definition: swresample_internal.h:48
AV_SAMPLE_FMT_NB
@ AV_SAMPLE_FMT_NB
Number of sample formats. DO NOT USE if linking dynamically.
Definition: samplefmt.h:74
LICENSE_PREFIX
#define LICENSE_PREFIX
SwrContext::preout
AudioData preout
pre-output audio data: used for rematrix/resample
Definition: swresample_internal.h:151
SWR_FLAG_RESAMPLE
#define SWR_FLAG_RESAMPLE
Force resampling even if equal sample rate.
Definition: swresample.h:136
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
swr_drop_output
int swr_drop_output(struct SwrContext *s, int count)
Drops the specified number of output samples.
Definition: swresample.c:828
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
size
int size
Definition: twinvq_data.h:11134
swri_get_dither
int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt)
Definition: dither.c:26
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
swr_free
av_cold void swr_free(SwrContext **ss)
Free the given SwrContext and set the pointer to NULL.
Definition: swresample.c:137
swri_rematrix_free
av_cold void swri_rematrix_free(SwrContext *s)
Definition: rematrix.c:490
SWR_ENGINE_SWR
@ SWR_ENGINE_SWR
SW Resampler.
Definition: swresample.h:160
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
a
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:41
swresample_internal.h
swri_audio_convert_alloc
AudioConvert * swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags)
Create an audio sample format converter context.
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:67
in
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
Definition: audio_convert.c:326
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
internal.h
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
SwrContext::max_soft_compensation
float max_soft_compensation
swr maximum soft compensation in seconds over soft_compensation_duration
Definition: swresample_internal.h:140
delta
float delta
Definition: vorbis_enc_data.h:457
uint8_t
uint8_t
Definition: audio_convert.c:194
swri_noise_shaping_double
void swri_noise_shaping_double(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count)
clear_context
static void clear_context(SwrContext *s)
Definition: swresample.c:114
ret
ret
Definition: filter_design.txt:187
RSC
#define RSC
SwrContext::in_sample_fmt
enum AVSampleFormat in_sample_fmt
input sample format
Definition: swresample_internal.h:99
set_audiodata_fmt
static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt)
Definition: swresample.c:101
AudioData::fmt
enum AVSampleFormat fmt
sample format
Definition: swresample_internal.h:52
channel_layout.h
MAX_DROP_STEP
#define MAX_DROP_STEP
swr_ffversion
const char swr_ffversion[]
Definition: swresample.c:33
swri_dither_init
av_cold int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt)
Definition: dither.c:79
swri_audio_convert_free
void swri_audio_convert_free(AudioConvert **ctx)
Free audio sample format converter context.
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
swri_rematrix_init
av_cold int swri_rematrix_init(SwrContext *s)
Definition: rematrix.c:385
swr_get_out_samples
int swr_get_out_samples(struct SwrContext *s, int in_samples)
Find an upper bound on the number of samples that the next swr_convert call will output,...
Definition: swresample.c:875
av_get_default_channel_layout
int64_t av_get_default_channel_layout(int nb_channels)
Return default channel layout for a given number of channels.
Definition: channel_layout.c:225
SwrContext::user_in_ch_layout
int64_t user_in_ch_layout
User set input channel layout.
Definition: swresample_internal.h:120
SwrContext::in_ch_layout
int64_t in_ch_layout
input channel layout
Definition: swresample_internal.h:102
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
swr_close
av_cold void swr_close(SwrContext *s)
Closes the context so that swr_is_initialized() returns 0.
Definition: swresample.c:148
swresample_configuration
const char * swresample_configuration(void)
Return the swr build-time configuration.
Definition: swresample.c:41
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
SWR_CH_MAX
#define SWR_CH_MAX
Definition: swresample.c:35
LIBSWRESAMPLE_VERSION_INT
#define LIBSWRESAMPLE_VERSION_INT
Definition: version.h:35
swresample_version
unsigned swresample_version(void)
Return the LIBSWRESAMPLE_VERSION_INT constant.
Definition: swresample.c:35
audioconvert.h