2 * Copyright (C) 2011-2013 Michael Niedermayer (michaelni@gmx.at)
4 * This file is part of libswresample
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.
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.
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
21 #include "libavutil/opt.h"
22 #include "swresample_internal.h"
23 #include "audioconvert.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/channel_layout.h"
31 unsigned swresample_version(void)
33 av_assert0(LIBSWRESAMPLE_VERSION_MICRO
>= 100);
34 return LIBSWRESAMPLE_VERSION_INT
;
37 const char *swresample_configuration(void)
39 return FFMPEG_CONFIGURATION
;
42 const char *swresample_license(void)
44 #define LICENSE_PREFIX "libswresample license: "
45 return LICENSE_PREFIX FFMPEG_LICENSE
+ sizeof(LICENSE_PREFIX
) - 1;
48 int swr_set_channel_mapping(struct SwrContext
*s
, const int *channel_map
){
49 if(!s
|| s
->in_convert
) // s needs to be allocated but not initialized
50 return AVERROR(EINVAL
);
51 s
->channel_map
= channel_map
;
55 struct SwrContext
*swr_alloc_set_opts(struct SwrContext
*s
,
56 int64_t out_ch_layout
, enum AVSampleFormat out_sample_fmt
, int out_sample_rate
,
57 int64_t in_ch_layout
, enum AVSampleFormat in_sample_fmt
, int in_sample_rate
,
58 int log_offset
, void *log_ctx
){
59 if(!s
) s
= swr_alloc();
62 s
->log_level_offset
= log_offset
;
65 if (av_opt_set_int(s
, "ocl", out_ch_layout
, 0) < 0)
68 if (av_opt_set_int(s
, "osf", out_sample_fmt
, 0) < 0)
71 if (av_opt_set_int(s
, "osr", out_sample_rate
, 0) < 0)
74 if (av_opt_set_int(s
, "icl", in_ch_layout
, 0) < 0)
77 if (av_opt_set_int(s
, "isf", in_sample_fmt
, 0) < 0)
80 if (av_opt_set_int(s
, "isr", in_sample_rate
, 0) < 0)
83 if (av_opt_set_int(s
, "tsf", AV_SAMPLE_FMT_NONE
, 0) < 0)
86 if (av_opt_set_int(s
, "ich", av_get_channel_layout_nb_channels(s
-> in_ch_layout
), 0) < 0)
89 if (av_opt_set_int(s
, "och", av_get_channel_layout_nb_channels(s
->out_ch_layout
), 0) < 0)
92 av_opt_set_int(s
, "uch", 0, 0);
95 av_log(s
, AV_LOG_ERROR
, "Failed to set option\n");
100 static void set_audiodata_fmt(AudioData
*a
, enum AVSampleFormat fmt
){
102 a
->bps
= av_get_bytes_per_sample(fmt
);
103 a
->planar
= av_sample_fmt_is_planar(fmt
);
104 if (a
->ch_count
== 1)
108 static void free_temp(AudioData
*a
){
110 memset(a
, 0, sizeof(*a
));
113 static void clear_context(SwrContext
*s
){
114 s
->in_buffer_index
= 0;
115 s
->in_buffer_count
= 0;
116 s
->resample_in_constraint
= 0;
117 memset(s
->in
.ch
, 0, sizeof(s
->in
.ch
));
118 memset(s
->out
.ch
, 0, sizeof(s
->out
.ch
));
119 free_temp(&s
->postin
);
120 free_temp(&s
->midbuf
);
121 free_temp(&s
->preout
);
122 free_temp(&s
->in_buffer
);
123 free_temp(&s
->silence
);
124 free_temp(&s
->drop_temp
);
125 free_temp(&s
->dither
.noise
);
126 free_temp(&s
->dither
.temp
);
127 swri_audio_convert_free(&s
-> in_convert
);
128 swri_audio_convert_free(&s
->out_convert
);
129 swri_audio_convert_free(&s
->full_convert
);
130 swri_rematrix_free(s
);
135 av_cold
void swr_free(SwrContext
**ss
){
140 s
->resampler
->free(&s
->resample
);
146 av_cold
void swr_close(SwrContext
*s
){
150 av_cold
int swr_init(struct SwrContext
*s
){
155 if(s
-> in_sample_fmt
>= AV_SAMPLE_FMT_NB
){
156 av_log(s
, AV_LOG_ERROR
, "Requested input sample format %d is invalid\n", s
->in_sample_fmt
);
157 return AVERROR(EINVAL
);
159 if(s
->out_sample_fmt
>= AV_SAMPLE_FMT_NB
){
160 av_log(s
, AV_LOG_ERROR
, "Requested output sample format %d is invalid\n", s
->out_sample_fmt
);
161 return AVERROR(EINVAL
);
164 if(av_get_channel_layout_nb_channels(s
-> in_ch_layout
) > SWR_CH_MAX
) {
165 av_log(s
, AV_LOG_WARNING
, "Input channel layout 0x%"PRIx64
" is invalid or unsupported.\n", s
-> in_ch_layout
);
169 if(av_get_channel_layout_nb_channels(s
->out_ch_layout
) > SWR_CH_MAX
) {
170 av_log(s
, AV_LOG_WARNING
, "Output channel layout 0x%"PRIx64
" is invalid or unsupported.\n", s
->out_ch_layout
);
171 s
->out_ch_layout
= 0;
176 extern struct Resampler
const soxr_resampler
;
177 case SWR_ENGINE_SOXR
: s
->resampler
= &soxr_resampler
; break;
179 case SWR_ENGINE_SWR
: s
->resampler
= &swri_resampler
; break;
181 av_log(s
, AV_LOG_ERROR
, "Requested resampling engine is unavailable\n");
182 return AVERROR(EINVAL
);
185 if(!s
->used_ch_count
)
186 s
->used_ch_count
= s
->in
.ch_count
;
188 if(s
->used_ch_count
&& s
-> in_ch_layout
&& s
->used_ch_count
!= av_get_channel_layout_nb_channels(s
-> in_ch_layout
)){
189 av_log(s
, AV_LOG_WARNING
, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
193 if(!s
-> in_ch_layout
)
194 s
-> in_ch_layout
= av_get_default_channel_layout(s
->used_ch_count
);
195 if(!s
->out_ch_layout
)
196 s
->out_ch_layout
= av_get_default_channel_layout(s
->out
.ch_count
);
198 s
->rematrix
= s
->out_ch_layout
!=s
->in_ch_layout
|| s
->rematrix_volume
!=1.0 ||
201 if(s
->int_sample_fmt
== AV_SAMPLE_FMT_NONE
){
202 if(av_get_planar_sample_fmt(s
->in_sample_fmt
) <= AV_SAMPLE_FMT_S16P
){
203 s
->int_sample_fmt
= AV_SAMPLE_FMT_S16P
;
204 }else if( av_get_planar_sample_fmt(s
-> in_sample_fmt
) == AV_SAMPLE_FMT_S32P
205 && av_get_planar_sample_fmt(s
->out_sample_fmt
) == AV_SAMPLE_FMT_S32P
207 && s
->engine
!= SWR_ENGINE_SOXR
){
208 s
->int_sample_fmt
= AV_SAMPLE_FMT_S32P
;
209 }else if(av_get_planar_sample_fmt(s
->in_sample_fmt
) <= AV_SAMPLE_FMT_FLTP
){
210 s
->int_sample_fmt
= AV_SAMPLE_FMT_FLTP
;
212 av_log(s
, AV_LOG_DEBUG
, "Using double precision mode\n");
213 s
->int_sample_fmt
= AV_SAMPLE_FMT_DBLP
;
217 if( s
->int_sample_fmt
!= AV_SAMPLE_FMT_S16P
218 &&s
->int_sample_fmt
!= AV_SAMPLE_FMT_S32P
219 &&s
->int_sample_fmt
!= AV_SAMPLE_FMT_FLTP
220 &&s
->int_sample_fmt
!= AV_SAMPLE_FMT_DBLP
){
221 av_log(s
, AV_LOG_ERROR
, "Requested sample format %s is not supported internally, S16/S32/FLT/DBL is supported\n", av_get_sample_fmt_name(s
->int_sample_fmt
));
222 return AVERROR(EINVAL
);
225 set_audiodata_fmt(&s
-> in
, s
-> in_sample_fmt
);
226 set_audiodata_fmt(&s
->out
, s
->out_sample_fmt
);
228 if (s
->firstpts_in_samples
!= AV_NOPTS_VALUE
) {
229 if (!s
->async
&& s
->min_compensation
>= FLT_MAX
/2)
232 s
->outpts
= s
->firstpts_in_samples
* s
->out_sample_rate
;
234 s
->firstpts
= AV_NOPTS_VALUE
;
237 if (s
->min_compensation
>= FLT_MAX
/2)
238 s
->min_compensation
= 0.001;
239 if (s
->async
> 1.0001) {
240 s
->max_soft_compensation
= s
->async
/ (double) s
->in_sample_rate
;
244 if (s
->out_sample_rate
!=s
->in_sample_rate
|| (s
->flags
& SWR_FLAG_RESAMPLE
)){
245 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
);
247 s
->resampler
->free(&s
->resample
);
248 if( s
->int_sample_fmt
!= AV_SAMPLE_FMT_S16P
249 && s
->int_sample_fmt
!= AV_SAMPLE_FMT_S32P
250 && s
->int_sample_fmt
!= AV_SAMPLE_FMT_FLTP
251 && s
->int_sample_fmt
!= AV_SAMPLE_FMT_DBLP
253 av_log(s
, AV_LOG_ERROR
, "Resampling only supported with internal s16/s32/flt/dbl\n");
257 #define RSC 1 //FIXME finetune
259 s
-> in
.ch_count
= av_get_channel_layout_nb_channels(s
-> in_ch_layout
);
260 if(!s
->used_ch_count
)
261 s
->used_ch_count
= s
->in
.ch_count
;
263 s
->out
.ch_count
= av_get_channel_layout_nb_channels(s
->out_ch_layout
);
265 if(!s
-> in
.ch_count
){
266 av_assert0(!s
->in_ch_layout
);
267 av_log(s
, AV_LOG_ERROR
, "Input channel count and layout are unset\n");
271 if ((!s
->out_ch_layout
|| !s
->in_ch_layout
) && s
->used_ch_count
!= s
->out
.ch_count
&& !s
->rematrix_custom
) {
272 char l1
[1024], l2
[1024];
273 av_get_channel_layout_string(l1
, sizeof(l1
), s
-> in
.ch_count
, s
-> in_ch_layout
);
274 av_get_channel_layout_string(l2
, sizeof(l2
), s
->out
.ch_count
, s
->out_ch_layout
);
275 av_log(s
, AV_LOG_ERROR
, "Rematrix is needed between %s and %s "
276 "but there is not enough information to do it\n", l1
, l2
);
280 av_assert0(s
->used_ch_count
);
281 av_assert0(s
->out
.ch_count
);
282 s
->resample_first
= RSC
*s
->out
.ch_count
/s
->in
.ch_count
- RSC
< s
->out_sample_rate
/(float)s
-> in_sample_rate
- 1.0;
286 s
->drop_temp
= s
->out
;
288 if(!s
->resample
&& !s
->rematrix
&& !s
->channel_map
&& !s
->dither
.method
){
289 s
->full_convert
= swri_audio_convert_alloc(s
->out_sample_fmt
,
290 s
-> in_sample_fmt
, s
-> in
.ch_count
, NULL
, 0);
294 s
->in_convert
= swri_audio_convert_alloc(s
->int_sample_fmt
,
295 s
-> in_sample_fmt
, s
->used_ch_count
, s
->channel_map
, 0);
296 s
->out_convert
= swri_audio_convert_alloc(s
->out_sample_fmt
,
297 s
->int_sample_fmt
, s
->out
.ch_count
, NULL
, 0);
299 if (!s
->in_convert
|| !s
->out_convert
)
300 return AVERROR(ENOMEM
);
308 s
->midbuf
.ch_count
= s
->used_ch_count
;
310 s
->in_buffer
.ch_count
= s
->used_ch_count
;
312 if(!s
->resample_first
){
313 s
->midbuf
.ch_count
= s
->out
.ch_count
;
315 s
->in_buffer
.ch_count
= s
->out
.ch_count
;
318 set_audiodata_fmt(&s
->postin
, s
->int_sample_fmt
);
319 set_audiodata_fmt(&s
->midbuf
, s
->int_sample_fmt
);
320 set_audiodata_fmt(&s
->preout
, s
->int_sample_fmt
);
323 set_audiodata_fmt(&s
->in_buffer
, s
->int_sample_fmt
);
326 if ((ret
= swri_dither_init(s
, s
->out_sample_fmt
, s
->int_sample_fmt
)) < 0)
329 if(s
->rematrix
|| s
->dither
.method
)
330 return swri_rematrix_init(s
);
335 int swri_realloc_audio(AudioData
*a
, int count
){
339 if(count
< 0 || count
> INT_MAX
/2/a
->bps
/a
->ch_count
)
340 return AVERROR(EINVAL
);
342 if(a
->count
>= count
)
347 countb
= FFALIGN(count
*a
->bps
, ALIGN
);
351 av_assert0(a
->ch_count
);
353 a
->data
= av_mallocz(countb
*a
->ch_count
);
355 return AVERROR(ENOMEM
);
356 for(i
=0; i
<a
->ch_count
; i
++){
357 a
->ch
[i
]= a
->data
+ i
*(a
->planar
? countb
: a
->bps
);
358 if(a
->planar
) memcpy(a
->ch
[i
], old
.ch
[i
], a
->count
*a
->bps
);
360 if(!a
->planar
) memcpy(a
->ch
[0], old
.ch
[0], a
->count
*a
->ch_count
*a
->bps
);
367 static void copy(AudioData
*out
, AudioData
*in
,
369 av_assert0(out
->planar
== in
->planar
);
370 av_assert0(out
->bps
== in
->bps
);
371 av_assert0(out
->ch_count
== in
->ch_count
);
374 for(ch
=0; ch
<out
->ch_count
; ch
++)
375 memcpy(out
->ch
[ch
], in
->ch
[ch
], count
*out
->bps
);
377 memcpy(out
->ch
[0], in
->ch
[0], count
*out
->ch_count
*out
->bps
);
380 static void fill_audiodata(AudioData
*out
, uint8_t *in_arg
[SWR_CH_MAX
]){
383 memset(out
->ch
, 0, sizeof(out
->ch
));
384 }else if(out
->planar
){
385 for(i
=0; i
<out
->ch_count
; i
++)
386 out
->ch
[i
]= in_arg
[i
];
388 for(i
=0; i
<out
->ch_count
; i
++)
389 out
->ch
[i
]= in_arg
[0] + i
*out
->bps
;
393 static void reversefill_audiodata(AudioData
*out
, uint8_t *in_arg
[SWR_CH_MAX
]){
396 for(i
=0; i
<out
->ch_count
; i
++)
397 in_arg
[i
]= out
->ch
[i
];
399 in_arg
[0]= out
->ch
[0];
405 * out may be equal in.
407 static void buf_set(AudioData
*out
, AudioData
*in
, int count
){
410 for(ch
=0; ch
<out
->ch_count
; ch
++)
411 out
->ch
[ch
]= in
->ch
[ch
] + count
*out
->bps
;
413 for(ch
=out
->ch_count
-1; ch
>=0; ch
--)
414 out
->ch
[ch
]= in
->ch
[0] + (ch
+ count
*out
->ch_count
) * out
->bps
;
420 * @return number of samples output per channel
422 static int resample(SwrContext
*s
, AudioData
*out_param
, int out_count
,
423 const AudioData
* in_param
, int in_count
){
424 AudioData in
, out
, tmp
;
427 int padless
= ARCH_X86
&& s
->engine
== SWR_ENGINE_SWR
? 7 : 0;
429 av_assert1(s
->in_buffer
.ch_count
== in_param
->ch_count
);
430 av_assert1(s
->in_buffer
.planar
== in_param
->planar
);
431 av_assert1(s
->in_buffer
.fmt
== in_param
->fmt
);
436 border
= s
->resampler
->invert_initial_buffer(s
->resample
, &s
->in_buffer
,
437 &in
, in_count
, &s
->in_buffer_index
, &s
->in_buffer_count
);
438 if (border
== INT_MAX
) {
440 } else if (border
< 0) {
443 buf_set(&in
, &in
, border
);
445 s
->resample_in_constraint
= 0;
449 int ret
, size
, consumed
;
450 if(!s
->resample_in_constraint
&& s
->in_buffer_count
){
451 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
452 ret
= s
->resampler
->multiple_resample(s
->resample
, &out
, out_count
, &tmp
, s
->in_buffer_count
, &consumed
);
455 buf_set(&out
, &out
, ret
);
456 s
->in_buffer_count
-= consumed
;
457 s
->in_buffer_index
+= consumed
;
461 if(s
->in_buffer_count
<= border
){
462 buf_set(&in
, &in
, -s
->in_buffer_count
);
463 in_count
+= s
->in_buffer_count
;
464 s
->in_buffer_count
=0;
465 s
->in_buffer_index
=0;
470 if((s
->flushed
|| in_count
> padless
) && !s
->in_buffer_count
){
471 s
->in_buffer_index
=0;
472 ret
= s
->resampler
->multiple_resample(s
->resample
, &out
, out_count
, &in
, FFMAX(in_count
-padless
, 0), &consumed
);
475 buf_set(&out
, &out
, ret
);
476 in_count
-= consumed
;
477 buf_set(&in
, &in
, consumed
);
480 //TODO is this check sane considering the advanced copy avoidance below
481 size
= s
->in_buffer_index
+ s
->in_buffer_count
+ in_count
;
482 if( size
> s
->in_buffer
.count
483 && s
->in_buffer_count
+ in_count
<= s
->in_buffer_index
){
484 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
485 copy(&s
->in_buffer
, &tmp
, s
->in_buffer_count
);
486 s
->in_buffer_index
=0;
488 if((ret
=swri_realloc_audio(&s
->in_buffer
, size
)) < 0)
493 if(s
->in_buffer_count
&& s
->in_buffer_count
+2 < count
&& out_count
) count
= s
->in_buffer_count
+2;
495 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
+ s
->in_buffer_count
);
496 copy(&tmp
, &in
, /*in_*/count
);
497 s
->in_buffer_count
+= count
;
500 buf_set(&in
, &in
, count
);
501 s
->resample_in_constraint
= 0;
502 if(s
->in_buffer_count
!= count
|| in_count
)
512 s
->resample_in_constraint
= !!out_count
;
517 static int swr_convert_internal(struct SwrContext
*s
, AudioData
*out
, int out_count
,
518 AudioData
*in
, int in_count
){
519 AudioData
*postin
, *midbuf
, *preout
;
521 AudioData preout_tmp
, midbuf_tmp
;
524 av_assert0(!s
->resample
);
525 swri_audio_convert(s
->full_convert
, out
, in
, in_count
);
529 // in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
530 // in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
532 if((ret
=swri_realloc_audio(&s
->postin
, in_count
))<0)
534 if(s
->resample_first
){
535 av_assert0(s
->midbuf
.ch_count
== s
->used_ch_count
);
536 if((ret
=swri_realloc_audio(&s
->midbuf
, out_count
))<0)
539 av_assert0(s
->midbuf
.ch_count
== s
->out
.ch_count
);
540 if((ret
=swri_realloc_audio(&s
->midbuf
, in_count
))<0)
543 if((ret
=swri_realloc_audio(&s
->preout
, out_count
))<0)
548 midbuf_tmp
= s
->midbuf
;
550 preout_tmp
= s
->preout
;
553 if(s
->int_sample_fmt
== s
-> in_sample_fmt
&& s
->in
.planar
&& !s
->channel_map
)
556 if(s
->resample_first
? !s
->resample
: !s
->rematrix
)
559 if(s
->resample_first
? !s
->rematrix
: !s
->resample
)
562 if(s
->int_sample_fmt
== s
->out_sample_fmt
&& s
->out
.planar
563 && !(s
->out_sample_fmt
==AV_SAMPLE_FMT_S32P
&& (s
->dither
.output_sample_bits
&31))){
565 out_count
= FFMIN(out_count
, in_count
); //TODO check at the end if this is needed or redundant
566 av_assert0(s
->in
.planar
); //we only support planar internally so it has to be, we support copying non planar though
567 copy(out
, in
, out_count
);
570 else if(preout
==postin
) preout
= midbuf
= postin
= out
;
571 else if(preout
==midbuf
) preout
= midbuf
= out
;
576 swri_audio_convert(s
->in_convert
, postin
, in
, in_count
);
579 if(s
->resample_first
){
581 out_count
= resample(s
, midbuf
, out_count
, postin
, in_count
);
583 swri_rematrix(s
, preout
, midbuf
, out_count
, preout
==out
);
586 swri_rematrix(s
, midbuf
, postin
, in_count
, midbuf
==out
);
588 out_count
= resample(s
, preout
, out_count
, midbuf
, in_count
);
591 if(preout
!= out
&& out_count
){
592 AudioData
*conv_src
= preout
;
593 if(s
->dither
.method
){
595 int dither_count
= FFMAX(out_count
, 1<<16);
598 conv_src
= &s
->dither
.temp
;
599 if((ret
=swri_realloc_audio(&s
->dither
.temp
, dither_count
))<0)
603 if((ret
=swri_realloc_audio(&s
->dither
.noise
, dither_count
))<0)
606 for(ch
=0; ch
<s
->dither
.noise
.ch_count
; ch
++)
607 swri_get_dither(s
, s
->dither
.noise
.ch
[ch
], s
->dither
.noise
.count
, 12345678913579<<ch
, s
->dither
.noise
.fmt
);
608 av_assert0(s
->dither
.noise
.ch_count
== preout
->ch_count
);
610 if(s
->dither
.noise_pos
+ out_count
> s
->dither
.noise
.count
)
611 s
->dither
.noise_pos
= 0;
613 if (s
->dither
.method
< SWR_DITHER_NS
){
614 if (s
->mix_2_1_simd
) {
615 int len1
= out_count
&~15;
616 int off
= len1
* preout
->bps
;
619 for(ch
=0; ch
<preout
->ch_count
; ch
++)
620 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
);
621 if(out_count
!= len1
)
622 for(ch
=0; ch
<preout
->ch_count
; ch
++)
623 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
+ len1
, s
->native_one
, 0, 0, out_count
- len1
);
625 for(ch
=0; ch
<preout
->ch_count
; ch
++)
626 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
);
629 switch(s
->int_sample_fmt
) {
630 case AV_SAMPLE_FMT_S16P
:swri_noise_shaping_int16(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
631 case AV_SAMPLE_FMT_S32P
:swri_noise_shaping_int32(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
632 case AV_SAMPLE_FMT_FLTP
:swri_noise_shaping_float(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
633 case AV_SAMPLE_FMT_DBLP
:swri_noise_shaping_double(s
,conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
636 s
->dither
.noise_pos
+= out_count
;
638 //FIXME packed doesn't need more than 1 chan here!
639 swri_audio_convert(s
->out_convert
, out
, conv_src
, out_count
);
644 int swr_is_initialized(struct SwrContext
*s
) {
645 return !!s
->in_buffer
.ch_count
;
648 int swr_convert(struct SwrContext
*s
, uint8_t *out_arg
[SWR_CH_MAX
], int out_count
,
649 const uint8_t *in_arg
[SWR_CH_MAX
], int in_count
){
650 AudioData
* in
= &s
->in
;
651 AudioData
*out
= &s
->out
;
653 if (!swr_is_initialized(s
)) {
654 av_log(s
, AV_LOG_ERROR
, "Context has not been initialized\n");
655 return AVERROR(EINVAL
);
658 while(s
->drop_output
> 0){
660 uint8_t *tmp_arg
[SWR_CH_MAX
];
661 #define MAX_DROP_STEP 16384
662 if((ret
=swri_realloc_audio(&s
->drop_temp
, FFMIN(s
->drop_output
, MAX_DROP_STEP
)))<0)
665 reversefill_audiodata(&s
->drop_temp
, tmp_arg
);
666 s
->drop_output
*= -1; //FIXME find a less hackish solution
667 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
668 s
->drop_output
*= -1;
671 s
->drop_output
-= ret
;
672 if (!s
->drop_output
&& !out_arg
)
677 av_assert0(s
->drop_output
);
684 s
->resampler
->flush(s
);
685 s
->resample_in_constraint
= 0;
687 }else if(!s
->in_buffer_count
){
691 fill_audiodata(in
, (void*)in_arg
);
693 fill_audiodata(out
, out_arg
);
696 int ret
= swr_convert_internal(s
, out
, out_count
, in
, in_count
);
697 if(ret
>0 && !s
->drop_output
)
698 s
->outpts
+= ret
* (int64_t)s
->in_sample_rate
;
704 size
= FFMIN(out_count
, s
->in_buffer_count
);
706 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
707 ret
= swr_convert_internal(s
, out
, size
, &tmp
, size
);
711 s
->in_buffer_count
-= ret
;
712 s
->in_buffer_index
+= ret
;
713 buf_set(out
, out
, ret
);
715 if(!s
->in_buffer_count
)
716 s
->in_buffer_index
= 0;
720 size
= s
->in_buffer_index
+ s
->in_buffer_count
+ in_count
- out_count
;
722 if(in_count
> out_count
) { //FIXME move after swr_convert_internal
723 if( size
> s
->in_buffer
.count
724 && s
->in_buffer_count
+ in_count
- out_count
<= s
->in_buffer_index
){
725 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
726 copy(&s
->in_buffer
, &tmp
, s
->in_buffer_count
);
727 s
->in_buffer_index
=0;
729 if((ret
=swri_realloc_audio(&s
->in_buffer
, size
)) < 0)
734 size
= FFMIN(in_count
, out_count
);
735 ret
= swr_convert_internal(s
, out
, size
, in
, size
);
738 buf_set(in
, in
, ret
);
743 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
+ s
->in_buffer_count
);
744 copy(&tmp
, in
, in_count
);
745 s
->in_buffer_count
+= in_count
;
748 if(ret2
>0 && !s
->drop_output
)
749 s
->outpts
+= ret2
* (int64_t)s
->in_sample_rate
;
754 int swr_drop_output(struct SwrContext
*s
, int count
){
755 const uint8_t *tmp_arg
[SWR_CH_MAX
];
756 s
->drop_output
+= count
;
758 if(s
->drop_output
<= 0)
761 av_log(s
, AV_LOG_VERBOSE
, "discarding %d audio samples\n", count
);
762 return swr_convert(s
, NULL
, s
->drop_output
, tmp_arg
, 0);
765 int swr_inject_silence(struct SwrContext
*s
, int count
){
767 uint8_t *tmp_arg
[SWR_CH_MAX
];
772 #define MAX_SILENCE_STEP 16384
773 while (count
> MAX_SILENCE_STEP
) {
774 if ((ret
= swr_inject_silence(s
, MAX_SILENCE_STEP
)) < 0)
776 count
-= MAX_SILENCE_STEP
;
779 if((ret
=swri_realloc_audio(&s
->silence
, count
))<0)
782 if(s
->silence
.planar
) for(i
=0; i
<s
->silence
.ch_count
; i
++) {
783 memset(s
->silence
.ch
[i
], s
->silence
.bps
==1 ? 0x80 : 0, count
*s
->silence
.bps
);
785 memset(s
->silence
.ch
[0], s
->silence
.bps
==1 ? 0x80 : 0, count
*s
->silence
.bps
*s
->silence
.ch_count
);
787 reversefill_audiodata(&s
->silence
, tmp_arg
);
788 av_log(s
, AV_LOG_VERBOSE
, "adding %d audio samples of silence\n", count
);
789 ret
= swr_convert(s
, NULL
, 0, (const uint8_t**)tmp_arg
, count
);
793 int64_t swr_get_delay(struct SwrContext
*s
, int64_t base
){
794 if (s
->resampler
&& s
->resample
){
795 return s
->resampler
->get_delay(s
, base
);
797 return (s
->in_buffer_count
*base
+ (s
->in_sample_rate
>>1))/ s
->in_sample_rate
;
801 int swr_set_compensation(struct SwrContext
*s
, int sample_delta
, int compensation_distance
){
804 if (!s
|| compensation_distance
< 0)
805 return AVERROR(EINVAL
);
806 if (!compensation_distance
&& sample_delta
)
807 return AVERROR(EINVAL
);
809 s
->flags
|= SWR_FLAG_RESAMPLE
;
814 if (!s
->resampler
->set_compensation
){
815 return AVERROR(EINVAL
);
817 return s
->resampler
->set_compensation(s
->resample
, sample_delta
, compensation_distance
);
821 int64_t swr_next_pts(struct SwrContext
*s
, int64_t pts
){
825 if (s
->firstpts
== AV_NOPTS_VALUE
)
826 s
->outpts
= s
->firstpts
= pts
;
828 if(s
->min_compensation
>= FLT_MAX
) {
829 return (s
->outpts
= pts
- swr_get_delay(s
, s
->in_sample_rate
* (int64_t)s
->out_sample_rate
));
831 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
;
832 double fdelta
= delta
/(double)(s
->in_sample_rate
* (int64_t)s
->out_sample_rate
);
834 if(fabs(fdelta
) > s
->min_compensation
) {
835 if(s
->outpts
== s
->firstpts
|| fabs(fdelta
) > s
->min_hard_compensation
){
837 if(delta
> 0) ret
= swr_inject_silence(s
, delta
/ s
->out_sample_rate
);
838 else ret
= swr_drop_output (s
, -delta
/ s
-> in_sample_rate
);
840 av_log(s
, AV_LOG_ERROR
, "Failed to compensate for timestamp delta of %f\n", fdelta
);
842 } else if(s
->soft_compensation_duration
&& s
->max_soft_compensation
) {
843 int duration
= s
->out_sample_rate
* s
->soft_compensation_duration
;
844 double max_soft_compensation
= s
->max_soft_compensation
/ (s
->max_soft_compensation
< 0 ? -s
->in_sample_rate
: 1);
845 int comp
= av_clipf(fdelta
, -max_soft_compensation
, max_soft_compensation
) * duration
;
846 av_log(s
, AV_LOG_VERBOSE
, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta
, comp
, duration
);
847 swr_set_compensation(s
, comp
, duration
);