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
) return 0;
439 else if (border
< 0) return border
;
440 else if (border
) { buf_set(&in
, &in
, border
); in_count
-= border
; s
->resample_in_constraint
= 0; }
443 int ret
, size
, consumed
;
444 if(!s
->resample_in_constraint
&& s
->in_buffer_count
){
445 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
446 ret
= s
->resampler
->multiple_resample(s
->resample
, &out
, out_count
, &tmp
, s
->in_buffer_count
, &consumed
);
449 buf_set(&out
, &out
, ret
);
450 s
->in_buffer_count
-= consumed
;
451 s
->in_buffer_index
+= consumed
;
455 if(s
->in_buffer_count
<= border
){
456 buf_set(&in
, &in
, -s
->in_buffer_count
);
457 in_count
+= s
->in_buffer_count
;
458 s
->in_buffer_count
=0;
459 s
->in_buffer_index
=0;
464 if((s
->flushed
|| in_count
> padless
) && !s
->in_buffer_count
){
465 s
->in_buffer_index
=0;
466 ret
= s
->resampler
->multiple_resample(s
->resample
, &out
, out_count
, &in
, FFMAX(in_count
-padless
, 0), &consumed
);
469 buf_set(&out
, &out
, ret
);
470 in_count
-= consumed
;
471 buf_set(&in
, &in
, consumed
);
474 //TODO is this check sane considering the advanced copy avoidance below
475 size
= s
->in_buffer_index
+ s
->in_buffer_count
+ in_count
;
476 if( size
> s
->in_buffer
.count
477 && s
->in_buffer_count
+ in_count
<= s
->in_buffer_index
){
478 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
479 copy(&s
->in_buffer
, &tmp
, s
->in_buffer_count
);
480 s
->in_buffer_index
=0;
482 if((ret
=swri_realloc_audio(&s
->in_buffer
, size
)) < 0)
487 if(s
->in_buffer_count
&& s
->in_buffer_count
+2 < count
&& out_count
) count
= s
->in_buffer_count
+2;
489 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
+ s
->in_buffer_count
);
490 copy(&tmp
, &in
, /*in_*/count
);
491 s
->in_buffer_count
+= count
;
494 buf_set(&in
, &in
, count
);
495 s
->resample_in_constraint
= 0;
496 if(s
->in_buffer_count
!= count
|| in_count
)
506 s
->resample_in_constraint
= !!out_count
;
511 static int swr_convert_internal(struct SwrContext
*s
, AudioData
*out
, int out_count
,
512 AudioData
*in
, int in_count
){
513 AudioData
*postin
, *midbuf
, *preout
;
515 AudioData preout_tmp
, midbuf_tmp
;
518 av_assert0(!s
->resample
);
519 swri_audio_convert(s
->full_convert
, out
, in
, in_count
);
523 // in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
524 // in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
526 if((ret
=swri_realloc_audio(&s
->postin
, in_count
))<0)
528 if(s
->resample_first
){
529 av_assert0(s
->midbuf
.ch_count
== s
->used_ch_count
);
530 if((ret
=swri_realloc_audio(&s
->midbuf
, out_count
))<0)
533 av_assert0(s
->midbuf
.ch_count
== s
->out
.ch_count
);
534 if((ret
=swri_realloc_audio(&s
->midbuf
, in_count
))<0)
537 if((ret
=swri_realloc_audio(&s
->preout
, out_count
))<0)
542 midbuf_tmp
= s
->midbuf
;
544 preout_tmp
= s
->preout
;
547 if(s
->int_sample_fmt
== s
-> in_sample_fmt
&& s
->in
.planar
&& !s
->channel_map
)
550 if(s
->resample_first
? !s
->resample
: !s
->rematrix
)
553 if(s
->resample_first
? !s
->rematrix
: !s
->resample
)
556 if(s
->int_sample_fmt
== s
->out_sample_fmt
&& s
->out
.planar
557 && !(s
->out_sample_fmt
==AV_SAMPLE_FMT_S32P
&& (s
->dither
.output_sample_bits
&31))){
559 out_count
= FFMIN(out_count
, in_count
); //TODO check at the end if this is needed or redundant
560 av_assert0(s
->in
.planar
); //we only support planar internally so it has to be, we support copying non planar though
561 copy(out
, in
, out_count
);
564 else if(preout
==postin
) preout
= midbuf
= postin
= out
;
565 else if(preout
==midbuf
) preout
= midbuf
= out
;
570 swri_audio_convert(s
->in_convert
, postin
, in
, in_count
);
573 if(s
->resample_first
){
575 out_count
= resample(s
, midbuf
, out_count
, postin
, in_count
);
577 swri_rematrix(s
, preout
, midbuf
, out_count
, preout
==out
);
580 swri_rematrix(s
, midbuf
, postin
, in_count
, midbuf
==out
);
582 out_count
= resample(s
, preout
, out_count
, midbuf
, in_count
);
585 if(preout
!= out
&& out_count
){
586 AudioData
*conv_src
= preout
;
587 if(s
->dither
.method
){
589 int dither_count
= FFMAX(out_count
, 1<<16);
592 conv_src
= &s
->dither
.temp
;
593 if((ret
=swri_realloc_audio(&s
->dither
.temp
, dither_count
))<0)
597 if((ret
=swri_realloc_audio(&s
->dither
.noise
, dither_count
))<0)
600 for(ch
=0; ch
<s
->dither
.noise
.ch_count
; ch
++)
601 swri_get_dither(s
, s
->dither
.noise
.ch
[ch
], s
->dither
.noise
.count
, 12345678913579<<ch
, s
->dither
.noise
.fmt
);
602 av_assert0(s
->dither
.noise
.ch_count
== preout
->ch_count
);
604 if(s
->dither
.noise_pos
+ out_count
> s
->dither
.noise
.count
)
605 s
->dither
.noise_pos
= 0;
607 if (s
->dither
.method
< SWR_DITHER_NS
){
608 if (s
->mix_2_1_simd
) {
609 int len1
= out_count
&~15;
610 int off
= len1
* preout
->bps
;
613 for(ch
=0; ch
<preout
->ch_count
; ch
++)
614 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
);
615 if(out_count
!= len1
)
616 for(ch
=0; ch
<preout
->ch_count
; ch
++)
617 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
);
619 for(ch
=0; ch
<preout
->ch_count
; ch
++)
620 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
);
623 switch(s
->int_sample_fmt
) {
624 case AV_SAMPLE_FMT_S16P
:swri_noise_shaping_int16(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
625 case AV_SAMPLE_FMT_S32P
:swri_noise_shaping_int32(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
626 case AV_SAMPLE_FMT_FLTP
:swri_noise_shaping_float(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
627 case AV_SAMPLE_FMT_DBLP
:swri_noise_shaping_double(s
,conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
630 s
->dither
.noise_pos
+= out_count
;
632 //FIXME packed doesn't need more than 1 chan here!
633 swri_audio_convert(s
->out_convert
, out
, conv_src
, out_count
);
638 int swr_is_initialized(struct SwrContext
*s
) {
639 return !!s
->in_buffer
.ch_count
;
642 int swr_convert(struct SwrContext
*s
, uint8_t *out_arg
[SWR_CH_MAX
], int out_count
,
643 const uint8_t *in_arg
[SWR_CH_MAX
], int in_count
){
644 AudioData
* in
= &s
->in
;
645 AudioData
*out
= &s
->out
;
647 if (!swr_is_initialized(s
)) {
648 av_log(s
, AV_LOG_ERROR
, "Context has not been initialized\n");
649 return AVERROR(EINVAL
);
652 while(s
->drop_output
> 0){
654 uint8_t *tmp_arg
[SWR_CH_MAX
];
655 #define MAX_DROP_STEP 16384
656 if((ret
=swri_realloc_audio(&s
->drop_temp
, FFMIN(s
->drop_output
, MAX_DROP_STEP
)))<0)
659 reversefill_audiodata(&s
->drop_temp
, tmp_arg
);
660 s
->drop_output
*= -1; //FIXME find a less hackish solution
661 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
662 s
->drop_output
*= -1;
665 s
->drop_output
-= ret
;
666 if (!s
->drop_output
&& !out_arg
)
671 if(s
->drop_output
|| !out_arg
)
678 s
->resampler
->flush(s
);
679 s
->resample_in_constraint
= 0;
681 }else if(!s
->in_buffer_count
){
685 fill_audiodata(in
, (void*)in_arg
);
687 fill_audiodata(out
, out_arg
);
690 int ret
= swr_convert_internal(s
, out
, out_count
, in
, in_count
);
691 if(ret
>0 && !s
->drop_output
)
692 s
->outpts
+= ret
* (int64_t)s
->in_sample_rate
;
698 size
= FFMIN(out_count
, s
->in_buffer_count
);
700 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
701 ret
= swr_convert_internal(s
, out
, size
, &tmp
, size
);
705 s
->in_buffer_count
-= ret
;
706 s
->in_buffer_index
+= ret
;
707 buf_set(out
, out
, ret
);
709 if(!s
->in_buffer_count
)
710 s
->in_buffer_index
= 0;
714 size
= s
->in_buffer_index
+ s
->in_buffer_count
+ in_count
- out_count
;
716 if(in_count
> out_count
) { //FIXME move after swr_convert_internal
717 if( size
> s
->in_buffer
.count
718 && s
->in_buffer_count
+ in_count
- out_count
<= s
->in_buffer_index
){
719 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
720 copy(&s
->in_buffer
, &tmp
, s
->in_buffer_count
);
721 s
->in_buffer_index
=0;
723 if((ret
=swri_realloc_audio(&s
->in_buffer
, size
)) < 0)
728 size
= FFMIN(in_count
, out_count
);
729 ret
= swr_convert_internal(s
, out
, size
, in
, size
);
732 buf_set(in
, in
, ret
);
737 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
+ s
->in_buffer_count
);
738 copy(&tmp
, in
, in_count
);
739 s
->in_buffer_count
+= in_count
;
742 if(ret2
>0 && !s
->drop_output
)
743 s
->outpts
+= ret2
* (int64_t)s
->in_sample_rate
;
748 int swr_drop_output(struct SwrContext
*s
, int count
){
749 s
->drop_output
+= count
;
751 if(s
->drop_output
<= 0)
754 av_log(s
, AV_LOG_VERBOSE
, "discarding %d audio samples\n", count
);
755 return swr_convert(s
, NULL
, s
->drop_output
, NULL
, 0);
758 int swr_inject_silence(struct SwrContext
*s
, int count
){
760 uint8_t *tmp_arg
[SWR_CH_MAX
];
765 #define MAX_SILENCE_STEP 16384
766 while (count
> MAX_SILENCE_STEP
) {
767 if ((ret
= swr_inject_silence(s
, MAX_SILENCE_STEP
)) < 0)
769 count
-= MAX_SILENCE_STEP
;
772 if((ret
=swri_realloc_audio(&s
->silence
, count
))<0)
775 if(s
->silence
.planar
) for(i
=0; i
<s
->silence
.ch_count
; i
++) {
776 memset(s
->silence
.ch
[i
], s
->silence
.bps
==1 ? 0x80 : 0, count
*s
->silence
.bps
);
778 memset(s
->silence
.ch
[0], s
->silence
.bps
==1 ? 0x80 : 0, count
*s
->silence
.bps
*s
->silence
.ch_count
);
780 reversefill_audiodata(&s
->silence
, tmp_arg
);
781 av_log(s
, AV_LOG_VERBOSE
, "adding %d audio samples of silence\n", count
);
782 ret
= swr_convert(s
, NULL
, 0, (const uint8_t**)tmp_arg
, count
);
786 int64_t swr_get_delay(struct SwrContext
*s
, int64_t base
){
787 if (s
->resampler
&& s
->resample
){
788 return s
->resampler
->get_delay(s
, base
);
790 return (s
->in_buffer_count
*base
+ (s
->in_sample_rate
>>1))/ s
->in_sample_rate
;
794 int swr_set_compensation(struct SwrContext
*s
, int sample_delta
, int compensation_distance
){
797 if (!s
|| compensation_distance
< 0)
798 return AVERROR(EINVAL
);
799 if (!compensation_distance
&& sample_delta
)
800 return AVERROR(EINVAL
);
802 s
->flags
|= SWR_FLAG_RESAMPLE
;
807 if (!s
->resampler
->set_compensation
){
808 return AVERROR(EINVAL
);
810 return s
->resampler
->set_compensation(s
->resample
, sample_delta
, compensation_distance
);
814 int64_t swr_next_pts(struct SwrContext
*s
, int64_t pts
){
818 if (s
->firstpts
== AV_NOPTS_VALUE
)
819 s
->outpts
= s
->firstpts
= pts
;
821 if(s
->min_compensation
>= FLT_MAX
) {
822 return (s
->outpts
= pts
- swr_get_delay(s
, s
->in_sample_rate
* (int64_t)s
->out_sample_rate
));
824 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
;
825 double fdelta
= delta
/(double)(s
->in_sample_rate
* (int64_t)s
->out_sample_rate
);
827 if(fabs(fdelta
) > s
->min_compensation
) {
828 if(s
->outpts
== s
->firstpts
|| fabs(fdelta
) > s
->min_hard_compensation
){
830 if(delta
> 0) ret
= swr_inject_silence(s
, delta
/ s
->out_sample_rate
);
831 else ret
= swr_drop_output (s
, -delta
/ s
-> in_sample_rate
);
833 av_log(s
, AV_LOG_ERROR
, "Failed to compensate for timestamp delta of %f\n", fdelta
);
835 } else if(s
->soft_compensation_duration
&& s
->max_soft_compensation
) {
836 int duration
= s
->out_sample_rate
* s
->soft_compensation_duration
;
837 double max_soft_compensation
= s
->max_soft_compensation
/ (s
->max_soft_compensation
< 0 ? -s
->in_sample_rate
: 1);
838 int comp
= av_clipf(fdelta
, -max_soft_compensation
, max_soft_compensation
) * duration
;
839 av_log(s
, AV_LOG_VERBOSE
, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta
, comp
, duration
);
840 swr_set_compensation(s
, comp
, duration
);