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 #include "libavutil/ffversion.h"
32 const char swr_ffversion
[] = "FFmpeg version " FFMPEG_VERSION
;
34 unsigned swresample_version(void)
36 av_assert0(LIBSWRESAMPLE_VERSION_MICRO
>= 100);
37 return LIBSWRESAMPLE_VERSION_INT
;
40 const char *swresample_configuration(void)
42 return FFMPEG_CONFIGURATION
;
45 const char *swresample_license(void)
47 #define LICENSE_PREFIX "libswresample license: "
48 return LICENSE_PREFIX FFMPEG_LICENSE
+ sizeof(LICENSE_PREFIX
) - 1;
51 int swr_set_channel_mapping(struct SwrContext
*s
, const int *channel_map
){
52 if(!s
|| s
->in_convert
) // s needs to be allocated but not initialized
53 return AVERROR(EINVAL
);
54 s
->channel_map
= channel_map
;
58 struct SwrContext
*swr_alloc_set_opts(struct SwrContext
*s
,
59 int64_t out_ch_layout
, enum AVSampleFormat out_sample_fmt
, int out_sample_rate
,
60 int64_t in_ch_layout
, enum AVSampleFormat in_sample_fmt
, int in_sample_rate
,
61 int log_offset
, void *log_ctx
){
62 if(!s
) s
= swr_alloc();
65 s
->log_level_offset
= log_offset
;
68 if (av_opt_set_int(s
, "ocl", out_ch_layout
, 0) < 0)
71 if (av_opt_set_int(s
, "osf", out_sample_fmt
, 0) < 0)
74 if (av_opt_set_int(s
, "osr", out_sample_rate
, 0) < 0)
77 if (av_opt_set_int(s
, "icl", in_ch_layout
, 0) < 0)
80 if (av_opt_set_int(s
, "isf", in_sample_fmt
, 0) < 0)
83 if (av_opt_set_int(s
, "isr", in_sample_rate
, 0) < 0)
86 if (av_opt_set_int(s
, "tsf", AV_SAMPLE_FMT_NONE
, 0) < 0)
89 if (av_opt_set_int(s
, "ich", av_get_channel_layout_nb_channels(s
-> in_ch_layout
), 0) < 0)
92 if (av_opt_set_int(s
, "och", av_get_channel_layout_nb_channels(s
->out_ch_layout
), 0) < 0)
95 av_opt_set_int(s
, "uch", 0, 0);
98 av_log(s
, AV_LOG_ERROR
, "Failed to set option\n");
103 static void set_audiodata_fmt(AudioData
*a
, enum AVSampleFormat fmt
){
105 a
->bps
= av_get_bytes_per_sample(fmt
);
106 a
->planar
= av_sample_fmt_is_planar(fmt
);
107 if (a
->ch_count
== 1)
111 static void free_temp(AudioData
*a
){
113 memset(a
, 0, sizeof(*a
));
116 static void clear_context(SwrContext
*s
){
117 s
->in_buffer_index
= 0;
118 s
->in_buffer_count
= 0;
119 s
->resample_in_constraint
= 0;
120 memset(s
->in
.ch
, 0, sizeof(s
->in
.ch
));
121 memset(s
->out
.ch
, 0, sizeof(s
->out
.ch
));
122 free_temp(&s
->postin
);
123 free_temp(&s
->midbuf
);
124 free_temp(&s
->preout
);
125 free_temp(&s
->in_buffer
);
126 free_temp(&s
->silence
);
127 free_temp(&s
->drop_temp
);
128 free_temp(&s
->dither
.noise
);
129 free_temp(&s
->dither
.temp
);
130 swri_audio_convert_free(&s
-> in_convert
);
131 swri_audio_convert_free(&s
->out_convert
);
132 swri_audio_convert_free(&s
->full_convert
);
133 swri_rematrix_free(s
);
138 av_cold
void swr_free(SwrContext
**ss
){
143 s
->resampler
->free(&s
->resample
);
149 av_cold
void swr_close(SwrContext
*s
){
153 av_cold
int swr_init(struct SwrContext
*s
){
158 if(s
-> in_sample_fmt
>= AV_SAMPLE_FMT_NB
){
159 av_log(s
, AV_LOG_ERROR
, "Requested input sample format %d is invalid\n", s
->in_sample_fmt
);
160 return AVERROR(EINVAL
);
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
);
167 if(av_get_channel_layout_nb_channels(s
-> in_ch_layout
) > SWR_CH_MAX
) {
168 av_log(s
, AV_LOG_WARNING
, "Input channel layout 0x%"PRIx64
" is invalid or unsupported.\n", s
-> in_ch_layout
);
172 if(av_get_channel_layout_nb_channels(s
->out_ch_layout
) > SWR_CH_MAX
) {
173 av_log(s
, AV_LOG_WARNING
, "Output channel layout 0x%"PRIx64
" is invalid or unsupported.\n", s
->out_ch_layout
);
174 s
->out_ch_layout
= 0;
179 extern struct Resampler
const soxr_resampler
;
180 case SWR_ENGINE_SOXR
: s
->resampler
= &soxr_resampler
; break;
182 case SWR_ENGINE_SWR
: s
->resampler
= &swri_resampler
; break;
184 av_log(s
, AV_LOG_ERROR
, "Requested resampling engine is unavailable\n");
185 return AVERROR(EINVAL
);
188 if(!s
->used_ch_count
)
189 s
->used_ch_count
= s
->in
.ch_count
;
191 if(s
->used_ch_count
&& s
-> in_ch_layout
&& s
->used_ch_count
!= av_get_channel_layout_nb_channels(s
-> in_ch_layout
)){
192 av_log(s
, AV_LOG_WARNING
, "Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
196 if(!s
-> in_ch_layout
)
197 s
-> in_ch_layout
= av_get_default_channel_layout(s
->used_ch_count
);
198 if(!s
->out_ch_layout
)
199 s
->out_ch_layout
= av_get_default_channel_layout(s
->out
.ch_count
);
201 s
->rematrix
= s
->out_ch_layout
!=s
->in_ch_layout
|| s
->rematrix_volume
!=1.0 ||
204 if(s
->int_sample_fmt
== AV_SAMPLE_FMT_NONE
){
205 if(av_get_planar_sample_fmt(s
->in_sample_fmt
) <= AV_SAMPLE_FMT_S16P
){
206 s
->int_sample_fmt
= AV_SAMPLE_FMT_S16P
;
207 }else if( av_get_planar_sample_fmt(s
-> in_sample_fmt
) == AV_SAMPLE_FMT_S32P
208 && av_get_planar_sample_fmt(s
->out_sample_fmt
) == AV_SAMPLE_FMT_S32P
210 && s
->engine
!= SWR_ENGINE_SOXR
){
211 s
->int_sample_fmt
= AV_SAMPLE_FMT_S32P
;
212 }else if(av_get_planar_sample_fmt(s
->in_sample_fmt
) <= AV_SAMPLE_FMT_FLTP
){
213 s
->int_sample_fmt
= AV_SAMPLE_FMT_FLTP
;
215 av_log(s
, AV_LOG_DEBUG
, "Using double precision mode\n");
216 s
->int_sample_fmt
= AV_SAMPLE_FMT_DBLP
;
220 if( s
->int_sample_fmt
!= AV_SAMPLE_FMT_S16P
221 &&s
->int_sample_fmt
!= AV_SAMPLE_FMT_S32P
222 &&s
->int_sample_fmt
!= AV_SAMPLE_FMT_FLTP
223 &&s
->int_sample_fmt
!= AV_SAMPLE_FMT_DBLP
){
224 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
));
225 return AVERROR(EINVAL
);
228 set_audiodata_fmt(&s
-> in
, s
-> in_sample_fmt
);
229 set_audiodata_fmt(&s
->out
, s
->out_sample_fmt
);
231 if (s
->firstpts_in_samples
!= AV_NOPTS_VALUE
) {
232 if (!s
->async
&& s
->min_compensation
>= FLT_MAX
/2)
235 s
->outpts
= s
->firstpts_in_samples
* s
->out_sample_rate
;
237 s
->firstpts
= AV_NOPTS_VALUE
;
240 if (s
->min_compensation
>= FLT_MAX
/2)
241 s
->min_compensation
= 0.001;
242 if (s
->async
> 1.0001) {
243 s
->max_soft_compensation
= s
->async
/ (double) s
->in_sample_rate
;
247 if (s
->out_sample_rate
!=s
->in_sample_rate
|| (s
->flags
& SWR_FLAG_RESAMPLE
)){
248 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
);
250 s
->resampler
->free(&s
->resample
);
251 if( s
->int_sample_fmt
!= AV_SAMPLE_FMT_S16P
252 && s
->int_sample_fmt
!= AV_SAMPLE_FMT_S32P
253 && s
->int_sample_fmt
!= AV_SAMPLE_FMT_FLTP
254 && s
->int_sample_fmt
!= AV_SAMPLE_FMT_DBLP
256 av_log(s
, AV_LOG_ERROR
, "Resampling only supported with internal s16/s32/flt/dbl\n");
260 #define RSC 1 //FIXME finetune
262 s
-> in
.ch_count
= av_get_channel_layout_nb_channels(s
-> in_ch_layout
);
263 if(!s
->used_ch_count
)
264 s
->used_ch_count
= s
->in
.ch_count
;
266 s
->out
.ch_count
= av_get_channel_layout_nb_channels(s
->out_ch_layout
);
268 if(!s
-> in
.ch_count
){
269 av_assert0(!s
->in_ch_layout
);
270 av_log(s
, AV_LOG_ERROR
, "Input channel count and layout are unset\n");
274 if ((!s
->out_ch_layout
|| !s
->in_ch_layout
) && s
->used_ch_count
!= s
->out
.ch_count
&& !s
->rematrix_custom
) {
275 char l1
[1024], l2
[1024];
276 av_get_channel_layout_string(l1
, sizeof(l1
), s
-> in
.ch_count
, s
-> in_ch_layout
);
277 av_get_channel_layout_string(l2
, sizeof(l2
), s
->out
.ch_count
, s
->out_ch_layout
);
278 av_log(s
, AV_LOG_ERROR
, "Rematrix is needed between %s and %s "
279 "but there is not enough information to do it\n", l1
, l2
);
283 av_assert0(s
->used_ch_count
);
284 av_assert0(s
->out
.ch_count
);
285 s
->resample_first
= RSC
*s
->out
.ch_count
/s
->in
.ch_count
- RSC
< s
->out_sample_rate
/(float)s
-> in_sample_rate
- 1.0;
289 s
->drop_temp
= s
->out
;
291 if(!s
->resample
&& !s
->rematrix
&& !s
->channel_map
&& !s
->dither
.method
){
292 s
->full_convert
= swri_audio_convert_alloc(s
->out_sample_fmt
,
293 s
-> in_sample_fmt
, s
-> in
.ch_count
, NULL
, 0);
297 s
->in_convert
= swri_audio_convert_alloc(s
->int_sample_fmt
,
298 s
-> in_sample_fmt
, s
->used_ch_count
, s
->channel_map
, 0);
299 s
->out_convert
= swri_audio_convert_alloc(s
->out_sample_fmt
,
300 s
->int_sample_fmt
, s
->out
.ch_count
, NULL
, 0);
302 if (!s
->in_convert
|| !s
->out_convert
)
303 return AVERROR(ENOMEM
);
311 s
->midbuf
.ch_count
= s
->used_ch_count
;
313 s
->in_buffer
.ch_count
= s
->used_ch_count
;
315 if(!s
->resample_first
){
316 s
->midbuf
.ch_count
= s
->out
.ch_count
;
318 s
->in_buffer
.ch_count
= s
->out
.ch_count
;
321 set_audiodata_fmt(&s
->postin
, s
->int_sample_fmt
);
322 set_audiodata_fmt(&s
->midbuf
, s
->int_sample_fmt
);
323 set_audiodata_fmt(&s
->preout
, s
->int_sample_fmt
);
326 set_audiodata_fmt(&s
->in_buffer
, s
->int_sample_fmt
);
329 if ((ret
= swri_dither_init(s
, s
->out_sample_fmt
, s
->int_sample_fmt
)) < 0)
332 if(s
->rematrix
|| s
->dither
.method
)
333 return swri_rematrix_init(s
);
338 int swri_realloc_audio(AudioData
*a
, int count
){
342 if(count
< 0 || count
> INT_MAX
/2/a
->bps
/a
->ch_count
)
343 return AVERROR(EINVAL
);
345 if(a
->count
>= count
)
350 countb
= FFALIGN(count
*a
->bps
, ALIGN
);
354 av_assert0(a
->ch_count
);
356 a
->data
= av_mallocz(countb
*a
->ch_count
);
358 return AVERROR(ENOMEM
);
359 for(i
=0; i
<a
->ch_count
; i
++){
360 a
->ch
[i
]= a
->data
+ i
*(a
->planar
? countb
: a
->bps
);
361 if(a
->planar
) memcpy(a
->ch
[i
], old
.ch
[i
], a
->count
*a
->bps
);
363 if(!a
->planar
) memcpy(a
->ch
[0], old
.ch
[0], a
->count
*a
->ch_count
*a
->bps
);
370 static void copy(AudioData
*out
, AudioData
*in
,
372 av_assert0(out
->planar
== in
->planar
);
373 av_assert0(out
->bps
== in
->bps
);
374 av_assert0(out
->ch_count
== in
->ch_count
);
377 for(ch
=0; ch
<out
->ch_count
; ch
++)
378 memcpy(out
->ch
[ch
], in
->ch
[ch
], count
*out
->bps
);
380 memcpy(out
->ch
[0], in
->ch
[0], count
*out
->ch_count
*out
->bps
);
383 static void fill_audiodata(AudioData
*out
, uint8_t *in_arg
[SWR_CH_MAX
]){
386 memset(out
->ch
, 0, sizeof(out
->ch
));
387 }else if(out
->planar
){
388 for(i
=0; i
<out
->ch_count
; i
++)
389 out
->ch
[i
]= in_arg
[i
];
391 for(i
=0; i
<out
->ch_count
; i
++)
392 out
->ch
[i
]= in_arg
[0] + i
*out
->bps
;
396 static void reversefill_audiodata(AudioData
*out
, uint8_t *in_arg
[SWR_CH_MAX
]){
399 for(i
=0; i
<out
->ch_count
; i
++)
400 in_arg
[i
]= out
->ch
[i
];
402 in_arg
[0]= out
->ch
[0];
408 * out may be equal in.
410 static void buf_set(AudioData
*out
, AudioData
*in
, int count
){
413 for(ch
=0; ch
<out
->ch_count
; ch
++)
414 out
->ch
[ch
]= in
->ch
[ch
] + count
*out
->bps
;
416 for(ch
=out
->ch_count
-1; ch
>=0; ch
--)
417 out
->ch
[ch
]= in
->ch
[0] + (ch
+ count
*out
->ch_count
) * out
->bps
;
423 * @return number of samples output per channel
425 static int resample(SwrContext
*s
, AudioData
*out_param
, int out_count
,
426 const AudioData
* in_param
, int in_count
){
427 AudioData in
, out
, tmp
;
430 int padless
= ARCH_X86
&& s
->engine
== SWR_ENGINE_SWR
? 7 : 0;
432 av_assert1(s
->in_buffer
.ch_count
== in_param
->ch_count
);
433 av_assert1(s
->in_buffer
.planar
== in_param
->planar
);
434 av_assert1(s
->in_buffer
.fmt
== in_param
->fmt
);
439 border
= s
->resampler
->invert_initial_buffer(s
->resample
, &s
->in_buffer
,
440 &in
, in_count
, &s
->in_buffer_index
, &s
->in_buffer_count
);
441 if (border
== INT_MAX
) {
443 } else if (border
< 0) {
446 buf_set(&in
, &in
, border
);
448 s
->resample_in_constraint
= 0;
452 int ret
, size
, consumed
;
453 if(!s
->resample_in_constraint
&& s
->in_buffer_count
){
454 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
455 ret
= s
->resampler
->multiple_resample(s
->resample
, &out
, out_count
, &tmp
, s
->in_buffer_count
, &consumed
);
458 buf_set(&out
, &out
, ret
);
459 s
->in_buffer_count
-= consumed
;
460 s
->in_buffer_index
+= consumed
;
464 if(s
->in_buffer_count
<= border
){
465 buf_set(&in
, &in
, -s
->in_buffer_count
);
466 in_count
+= s
->in_buffer_count
;
467 s
->in_buffer_count
=0;
468 s
->in_buffer_index
=0;
473 if((s
->flushed
|| in_count
> padless
) && !s
->in_buffer_count
){
474 s
->in_buffer_index
=0;
475 ret
= s
->resampler
->multiple_resample(s
->resample
, &out
, out_count
, &in
, FFMAX(in_count
-padless
, 0), &consumed
);
478 buf_set(&out
, &out
, ret
);
479 in_count
-= consumed
;
480 buf_set(&in
, &in
, consumed
);
483 //TODO is this check sane considering the advanced copy avoidance below
484 size
= s
->in_buffer_index
+ s
->in_buffer_count
+ in_count
;
485 if( size
> s
->in_buffer
.count
486 && s
->in_buffer_count
+ in_count
<= s
->in_buffer_index
){
487 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
488 copy(&s
->in_buffer
, &tmp
, s
->in_buffer_count
);
489 s
->in_buffer_index
=0;
491 if((ret
=swri_realloc_audio(&s
->in_buffer
, size
)) < 0)
496 if(s
->in_buffer_count
&& s
->in_buffer_count
+2 < count
&& out_count
) count
= s
->in_buffer_count
+2;
498 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
+ s
->in_buffer_count
);
499 copy(&tmp
, &in
, /*in_*/count
);
500 s
->in_buffer_count
+= count
;
503 buf_set(&in
, &in
, count
);
504 s
->resample_in_constraint
= 0;
505 if(s
->in_buffer_count
!= count
|| in_count
)
515 s
->resample_in_constraint
= !!out_count
;
520 static int swr_convert_internal(struct SwrContext
*s
, AudioData
*out
, int out_count
,
521 AudioData
*in
, int in_count
){
522 AudioData
*postin
, *midbuf
, *preout
;
524 AudioData preout_tmp
, midbuf_tmp
;
527 av_assert0(!s
->resample
);
528 swri_audio_convert(s
->full_convert
, out
, in
, in_count
);
532 // in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;
533 // in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);
535 if((ret
=swri_realloc_audio(&s
->postin
, in_count
))<0)
537 if(s
->resample_first
){
538 av_assert0(s
->midbuf
.ch_count
== s
->used_ch_count
);
539 if((ret
=swri_realloc_audio(&s
->midbuf
, out_count
))<0)
542 av_assert0(s
->midbuf
.ch_count
== s
->out
.ch_count
);
543 if((ret
=swri_realloc_audio(&s
->midbuf
, in_count
))<0)
546 if((ret
=swri_realloc_audio(&s
->preout
, out_count
))<0)
551 midbuf_tmp
= s
->midbuf
;
553 preout_tmp
= s
->preout
;
556 if(s
->int_sample_fmt
== s
-> in_sample_fmt
&& s
->in
.planar
&& !s
->channel_map
)
559 if(s
->resample_first
? !s
->resample
: !s
->rematrix
)
562 if(s
->resample_first
? !s
->rematrix
: !s
->resample
)
565 if(s
->int_sample_fmt
== s
->out_sample_fmt
&& s
->out
.planar
566 && !(s
->out_sample_fmt
==AV_SAMPLE_FMT_S32P
&& (s
->dither
.output_sample_bits
&31))){
568 out_count
= FFMIN(out_count
, in_count
); //TODO check at the end if this is needed or redundant
569 av_assert0(s
->in
.planar
); //we only support planar internally so it has to be, we support copying non planar though
570 copy(out
, in
, out_count
);
573 else if(preout
==postin
) preout
= midbuf
= postin
= out
;
574 else if(preout
==midbuf
) preout
= midbuf
= out
;
579 swri_audio_convert(s
->in_convert
, postin
, in
, in_count
);
582 if(s
->resample_first
){
584 out_count
= resample(s
, midbuf
, out_count
, postin
, in_count
);
586 swri_rematrix(s
, preout
, midbuf
, out_count
, preout
==out
);
589 swri_rematrix(s
, midbuf
, postin
, in_count
, midbuf
==out
);
591 out_count
= resample(s
, preout
, out_count
, midbuf
, in_count
);
594 if(preout
!= out
&& out_count
){
595 AudioData
*conv_src
= preout
;
596 if(s
->dither
.method
){
598 int dither_count
= FFMAX(out_count
, 1<<16);
601 conv_src
= &s
->dither
.temp
;
602 if((ret
=swri_realloc_audio(&s
->dither
.temp
, dither_count
))<0)
606 if((ret
=swri_realloc_audio(&s
->dither
.noise
, dither_count
))<0)
609 for(ch
=0; ch
<s
->dither
.noise
.ch_count
; ch
++)
610 swri_get_dither(s
, s
->dither
.noise
.ch
[ch
], s
->dither
.noise
.count
, 12345678913579<<ch
, s
->dither
.noise
.fmt
);
611 av_assert0(s
->dither
.noise
.ch_count
== preout
->ch_count
);
613 if(s
->dither
.noise_pos
+ out_count
> s
->dither
.noise
.count
)
614 s
->dither
.noise_pos
= 0;
616 if (s
->dither
.method
< SWR_DITHER_NS
){
617 if (s
->mix_2_1_simd
) {
618 int len1
= out_count
&~15;
619 int off
= len1
* preout
->bps
;
622 for(ch
=0; ch
<preout
->ch_count
; ch
++)
623 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
);
624 if(out_count
!= len1
)
625 for(ch
=0; ch
<preout
->ch_count
; ch
++)
626 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
);
628 for(ch
=0; ch
<preout
->ch_count
; ch
++)
629 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
);
632 switch(s
->int_sample_fmt
) {
633 case AV_SAMPLE_FMT_S16P
:swri_noise_shaping_int16(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
634 case AV_SAMPLE_FMT_S32P
:swri_noise_shaping_int32(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
635 case AV_SAMPLE_FMT_FLTP
:swri_noise_shaping_float(s
, conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
636 case AV_SAMPLE_FMT_DBLP
:swri_noise_shaping_double(s
,conv_src
, preout
, &s
->dither
.noise
, out_count
); break;
639 s
->dither
.noise_pos
+= out_count
;
641 //FIXME packed doesn't need more than 1 chan here!
642 swri_audio_convert(s
->out_convert
, out
, conv_src
, out_count
);
647 int swr_is_initialized(struct SwrContext
*s
) {
648 return !!s
->in_buffer
.ch_count
;
651 int swr_convert(struct SwrContext
*s
, uint8_t *out_arg
[SWR_CH_MAX
], int out_count
,
652 const uint8_t *in_arg
[SWR_CH_MAX
], int in_count
){
653 AudioData
* in
= &s
->in
;
654 AudioData
*out
= &s
->out
;
656 if (!swr_is_initialized(s
)) {
657 av_log(s
, AV_LOG_ERROR
, "Context has not been initialized\n");
658 return AVERROR(EINVAL
);
661 while(s
->drop_output
> 0){
663 uint8_t *tmp_arg
[SWR_CH_MAX
];
664 #define MAX_DROP_STEP 16384
665 if((ret
=swri_realloc_audio(&s
->drop_temp
, FFMIN(s
->drop_output
, MAX_DROP_STEP
)))<0)
668 reversefill_audiodata(&s
->drop_temp
, tmp_arg
);
669 s
->drop_output
*= -1; //FIXME find a less hackish solution
670 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
671 s
->drop_output
*= -1;
674 s
->drop_output
-= ret
;
675 if (!s
->drop_output
&& !out_arg
)
680 av_assert0(s
->drop_output
);
687 s
->resampler
->flush(s
);
688 s
->resample_in_constraint
= 0;
690 }else if(!s
->in_buffer_count
){
694 fill_audiodata(in
, (void*)in_arg
);
696 fill_audiodata(out
, out_arg
);
699 int ret
= swr_convert_internal(s
, out
, out_count
, in
, in_count
);
700 if(ret
>0 && !s
->drop_output
)
701 s
->outpts
+= ret
* (int64_t)s
->in_sample_rate
;
707 size
= FFMIN(out_count
, s
->in_buffer_count
);
709 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
710 ret
= swr_convert_internal(s
, out
, size
, &tmp
, size
);
714 s
->in_buffer_count
-= ret
;
715 s
->in_buffer_index
+= ret
;
716 buf_set(out
, out
, ret
);
718 if(!s
->in_buffer_count
)
719 s
->in_buffer_index
= 0;
723 size
= s
->in_buffer_index
+ s
->in_buffer_count
+ in_count
- out_count
;
725 if(in_count
> out_count
) { //FIXME move after swr_convert_internal
726 if( size
> s
->in_buffer
.count
727 && s
->in_buffer_count
+ in_count
- out_count
<= s
->in_buffer_index
){
728 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
);
729 copy(&s
->in_buffer
, &tmp
, s
->in_buffer_count
);
730 s
->in_buffer_index
=0;
732 if((ret
=swri_realloc_audio(&s
->in_buffer
, size
)) < 0)
737 size
= FFMIN(in_count
, out_count
);
738 ret
= swr_convert_internal(s
, out
, size
, in
, size
);
741 buf_set(in
, in
, ret
);
746 buf_set(&tmp
, &s
->in_buffer
, s
->in_buffer_index
+ s
->in_buffer_count
);
747 copy(&tmp
, in
, in_count
);
748 s
->in_buffer_count
+= in_count
;
751 if(ret2
>0 && !s
->drop_output
)
752 s
->outpts
+= ret2
* (int64_t)s
->in_sample_rate
;
757 int swr_drop_output(struct SwrContext
*s
, int count
){
758 const uint8_t *tmp_arg
[SWR_CH_MAX
];
759 s
->drop_output
+= count
;
761 if(s
->drop_output
<= 0)
764 av_log(s
, AV_LOG_VERBOSE
, "discarding %d audio samples\n", count
);
765 return swr_convert(s
, NULL
, s
->drop_output
, tmp_arg
, 0);
768 int swr_inject_silence(struct SwrContext
*s
, int count
){
770 uint8_t *tmp_arg
[SWR_CH_MAX
];
775 #define MAX_SILENCE_STEP 16384
776 while (count
> MAX_SILENCE_STEP
) {
777 if ((ret
= swr_inject_silence(s
, MAX_SILENCE_STEP
)) < 0)
779 count
-= MAX_SILENCE_STEP
;
782 if((ret
=swri_realloc_audio(&s
->silence
, count
))<0)
785 if(s
->silence
.planar
) for(i
=0; i
<s
->silence
.ch_count
; i
++) {
786 memset(s
->silence
.ch
[i
], s
->silence
.bps
==1 ? 0x80 : 0, count
*s
->silence
.bps
);
788 memset(s
->silence
.ch
[0], s
->silence
.bps
==1 ? 0x80 : 0, count
*s
->silence
.bps
*s
->silence
.ch_count
);
790 reversefill_audiodata(&s
->silence
, tmp_arg
);
791 av_log(s
, AV_LOG_VERBOSE
, "adding %d audio samples of silence\n", count
);
792 ret
= swr_convert(s
, NULL
, 0, (const uint8_t**)tmp_arg
, count
);
796 int64_t swr_get_delay(struct SwrContext
*s
, int64_t base
){
797 if (s
->resampler
&& s
->resample
){
798 return s
->resampler
->get_delay(s
, base
);
800 return (s
->in_buffer_count
*base
+ (s
->in_sample_rate
>>1))/ s
->in_sample_rate
;
804 int swr_set_compensation(struct SwrContext
*s
, int sample_delta
, int compensation_distance
){
807 if (!s
|| compensation_distance
< 0)
808 return AVERROR(EINVAL
);
809 if (!compensation_distance
&& sample_delta
)
810 return AVERROR(EINVAL
);
812 s
->flags
|= SWR_FLAG_RESAMPLE
;
817 if (!s
->resampler
->set_compensation
){
818 return AVERROR(EINVAL
);
820 return s
->resampler
->set_compensation(s
->resample
, sample_delta
, compensation_distance
);
824 int64_t swr_next_pts(struct SwrContext
*s
, int64_t pts
){
828 if (s
->firstpts
== AV_NOPTS_VALUE
)
829 s
->outpts
= s
->firstpts
= pts
;
831 if(s
->min_compensation
>= FLT_MAX
) {
832 return (s
->outpts
= pts
- swr_get_delay(s
, s
->in_sample_rate
* (int64_t)s
->out_sample_rate
));
834 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
;
835 double fdelta
= delta
/(double)(s
->in_sample_rate
* (int64_t)s
->out_sample_rate
);
837 if(fabs(fdelta
) > s
->min_compensation
) {
838 if(s
->outpts
== s
->firstpts
|| fabs(fdelta
) > s
->min_hard_compensation
){
840 if(delta
> 0) ret
= swr_inject_silence(s
, delta
/ s
->out_sample_rate
);
841 else ret
= swr_drop_output (s
, -delta
/ s
-> in_sample_rate
);
843 av_log(s
, AV_LOG_ERROR
, "Failed to compensate for timestamp delta of %f\n", fdelta
);
845 } else if(s
->soft_compensation_duration
&& s
->max_soft_compensation
) {
846 int duration
= s
->out_sample_rate
* s
->soft_compensation_duration
;
847 double max_soft_compensation
= s
->max_soft_compensation
/ (s
->max_soft_compensation
< 0 ? -s
->in_sample_rate
: 1);
848 int comp
= av_clipf(fdelta
, -max_soft_compensation
, max_soft_compensation
) * duration
;
849 av_log(s
, AV_LOG_VERBOSE
, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta
, comp
, duration
);
850 swr_set_compensation(s
, comp
, duration
);