32 #include "libavutil/ffversion.h"
43 return FFMPEG_CONFIGURATION;
48 #define LICENSE_PREFIX "libswresample license: "
114 memset(a, 0,
sizeof(*a));
121 memset(s->
in.
ch, 0,
sizeof(s->
in.
ch));
156 char l1[1024], l2[1024];
200 av_log(s,
AV_LOG_WARNING,
"Input channel layout has a different number of channels than the number of used channels, ignoring layout\n");
250 if (s->
async > 1.0001) {
256 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);
273 #define RSC 1 //FIXME finetune
281 if(!s->
in.ch_count){
303 "but there is not enough information to do it\n", l1, l2);
379 if(a->
count >= count)
412 memcpy(out->
ch[ch], in->
ch[ch], count*out->
bps);
420 memset(out->
ch, 0,
sizeof(out->
ch));
423 out->
ch[i]= in_arg[i];
426 out->
ch[i]= in_arg[0] + i*out->
bps;
434 in_arg[i]= out->
ch[i];
436 in_arg[0]= out->
ch[0];
448 out->
ch[ch]= in->
ch[ch] + count*out->
bps;
450 for(ch=out->
ch_count-1; ch>=0; ch--)
460 const AudioData * in_param,
int in_count){
475 if (border == INT_MAX) {
477 }
else if (border < 0) {
513 in_count -= consumed;
533 copy(&tmp, &in, count);
602 out_count=
FFMIN(out_count, in_count);
604 copy(out, in, out_count);
607 else if(preout==postin) preout= midbuf= postin=
out;
608 else if(preout==midbuf) preout= midbuf=
out;
618 out_count=
resample(s, midbuf, out_count, postin, in_count);
625 out_count=
resample(s, preout, out_count, midbuf, in_count);
628 if(preout != out && out_count){
632 int dither_count=
FFMAX(out_count, 1<<16);
653 int len1= out_count&~15;
654 int off = len1 * preout->
bps;
657 for(ch=0; ch<preout->
ch_count; ch++)
659 if(out_count != len1)
660 for(ch=0; ch<preout->
ch_count; ch++)
663 for(ch=0; ch<preout->
ch_count; ch++)
687 const uint8_t *in_arg [SWR_CH_MAX],
int in_count){
696 #if defined(ASSERT_LEVEL) && ASSERT_LEVEL >1
703 #define MAX_DROP_STEP 16384
742 av_assert2(max_output < 0 || ret < 0 || ret <= max_output);
767 if(in_count > out_count) {
779 size =
FFMIN(in_count, out_count);
789 copy(&tmp, in, in_count);
795 av_assert2(max_output < 0 || ret2 < 0 || ret2 <= max_output);
818 #define MAX_SILENCE_STEP 16384
863 if (out_samples > INT_MAX)
872 if (!s || compensation_distance < 0)
874 if (!compensation_distance && sample_delta)
913 int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) *
duration ;
914 av_log(s,
AV_LOG_VERBOSE,
"compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
struct AudioConvert * in_convert
input conversion context
struct AudioConvert * full_convert
full conversion context (single conversion for input and output)
Number of sample formats. DO NOT USE if linking dynamically.
AudioData temp
temporary storage when writing into the input buffer isn't possible
av_cold void swr_close(SwrContext *s)
Closes the context so that swr_is_initialized() returns 0.
int out_sample_rate
output sample rate
enum AVSampleFormat int_sample_fmt
internal sample format (AV_SAMPLE_FMT_FLTP or AV_SAMPLE_FMT_S16P)
Audio buffer used for intermediate storage between conversion phases.
enum AVResampleDitherMethod method
multiple_resample_func multiple_resample
#define AV_LOG_WARNING
Something somehow does not look correct.
int count
number of samples
int ch_count
number of channels
void swri_audio_convert_free(AudioConvert **ctx)
Free audio sample format converter context.
float soft_compensation_duration
swr duration over which soft compensation is applied
int rematrix_custom
flag to indicate that a custom matrix has been defined
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy)
int in_buffer_index
cached buffer position
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...
AudioData in_buffer
cached audio data (convert and resample purpose)
int resample_in_constraint
1 if the input end was reach before the output end, 0 otherwise
struct ResampleContext * resample
resampling context
static void reversefill_audiodata(AudioData *out, uint8_t *in_arg[SWR_CH_MAX])
float async
swr simple 1 parameter async, similar to ffmpegs -async
const int * channel_map
channel index (or -1 if muted channel) map
int av_get_channel_layout_nb_channels(uint64_t channel_layout)
Return the number of channels in the channel layout.
int log_level_offset
logging level offset
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, if called with in_samples of input samples.
struct Resampler const * resampler
resampler virtual function table
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance)
Activate resampling compensation ("soft" compensation).
av_cold int swri_rematrix_init(SwrContext *s)
av_cold struct SwrContext * swr_alloc(void)
Allocate SwrContext.
float max_soft_compensation
swr maximum soft compensation in seconds over soft_compensation_duration
int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt)
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.
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
int user_out_ch_count
User set output channel count.
enum AVSampleFormat fmt
sample format
void * log_ctx
parent logging context
AudioData out
converted output audio data
int swri_realloc_audio(AudioData *a, int count)
int phase_shift
log2 of the number of entries in the resampling polyphase filterbank
AudioData in
input audio data
uint8_t * native_simd_one
invert_initial_buffer_func invert_initial_buffer
float min_hard_compensation
swr minimum below which no silence inject / sample drop will happen
struct Resampler const swri_resampler
#define AV_LOG_VERBOSE
Detailed information.
enum AVSampleFormat av_get_planar_sample_fmt(enum AVSampleFormat sample_fmt)
Get the planar alternative form of the given sample format.
static void clear_context(SwrContext *s)
enum AVSampleFormat out_sample_fmt
output sample format
#define LIBSWRESAMPLE_VERSION_MICRO
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
int in_buffer_count
cached buffer length
AudioData postin
post-input audio data: used for rematrix/resample
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int output_sample_bits
the number of used output bits, needed to scale dither correctly
av_cold int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt)
int64_t user_in_ch_layout
User set input channel layout.
static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count, AudioData *in, int in_count)
The libswresample context.
double cutoff
resampling cutoff frequency (swr: 6dB point; soxr: 0dB point).
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static void buf_set(AudioData *out, AudioData *in, int count)
out may be equal in.
int av_opt_set_int(void *obj, const char *name, int64_t val, int search_flags)
simple assert() macros that are a bit more flexible than ISO C assert().
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.
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.
mix_2_1_func_type * mix_2_1_simd
resample_flush_func flush
int64_t firstpts
first PTS
AudioData preout
pre-output audio data: used for rematrix/resample
#define SWR_FLAG_RESAMPLE
Force resampling even if equal sample rate.
AudioData midbuf
intermediate audio data (postin/preout)
common internal API header
#define LIBSWRESAMPLE_VERSION_INT
audio channel layout utility functions
int flags
miscellaneous flags such as SWR_FLAG_RESAMPLE
int filter_type
swr resampling filter type
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static void free_temp(AudioData *a)
int swr_drop_output(struct SwrContext *s, int count)
Drops the specified number of output samples.
int drop_output
number of output samples to drop
int linear_interp
if 1 then the resampling FIR filter will be linearly interpolated
void swri_noise_shaping_int32(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count)
double precision
soxr resampling precision (in bits)
AudioData noise
noise used for dithering
int64_t out_ch_layout
output channel layout
struct SwrContext * swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, int log_offset, void *log_ctx)
Allocate SwrContext if needed and set/reset common parameters.
int in_sample_rate
input sample rate
int rematrix
flag to indicate if rematrixing is needed (basically if input and output layouts mismatch) ...
set_compensation_func set_compensation
const char swr_ffversion[]
static void copy(AudioData *out, AudioData *in, int count)
void swri_noise_shaping_double(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count)
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.
int user_in_ch_count
User set input channel count.
AVSampleFormat
Audio sample formats.
int user_used_ch_count
User set used channel count.
int filter_size
length of each FIR filter in the resampling filterbank relative to the cutoff frequency ...
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
av_cold void swr_free(SwrContext **ss)
Free the given SwrContext and set the pointer to NULL.
float min_compensation
swr minimum below which no compensation will happen
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;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);returnNULL;}returnac;}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;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->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);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map)
Set a customized input channel mapping.
struct DitherContext dither
void swri_noise_shaping_float(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count)
static void fill_audiodata(AudioData *out, uint8_t *in_arg[SWR_CH_MAX])
const char * swresample_license(void)
Return the swr license.
static int resample(SwrContext *s, AudioData *out_param, int out_count, const AudioData *in_param, int in_count)
get_out_samples_func get_out_samples
enum AVSampleFormat in_sample_fmt
input sample format
int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count, const uint8_t *in_arg[SWR_CH_MAX], int in_count)
Audio format conversion routines.
static int64_t pts
Global timestamp for the audio frames.
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
int flushed
1 if data is to be flushed and no further input is expected
int64_t in_ch_layout
input channel layout
int cheby
soxr: if 1 then passband rolloff will be none (Chebyshev) & irrational ratio approximation precision ...
void swri_noise_shaping_int16(SwrContext *s, AudioData *dsts, const AudioData *srcs, const AudioData *noises, int count)
int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len)
Convert between audio sample formats.
unsigned swresample_version(void)
Return the LIBSWRESAMPLE_VERSION_INT constant.
av_cold void swri_rematrix_free(SwrContext *s)
struct AudioConvert * out_convert
output conversion context
float rematrix_volume
rematrixing volume coefficient
static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt)
int kaiser_beta
swr beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) ...
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;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);returnNULL;}returnac;}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;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->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);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> out
mix_2_1_func_type * mix_2_1_f
int64_t firstpts_in_samples
swr first pts in samples
int64_t av_get_default_channel_layout(int nb_channels)
Return default channel layout for a given number of channels.
static void * av_mallocz_array(size_t nmemb, size_t size)
static void comp(unsigned char *dst, int dst_stride, unsigned char *src, int src_stride, int add)
int planar
1 if planar audio, 0 otherwise
AudioData drop_temp
temporary used to discard output
int swr_is_initialized(struct SwrContext *s)
Check whether an swr context has been initialized or not.
struct Resampler const swri_soxr_resampler
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel
int used_ch_count
number of used input channels (mapped channel count if channel_map, otherwise in.ch_count) ...
const char * swresample_configuration(void)
Return the swr build-time configuration.
int64_t user_out_ch_layout
User set output channel layout.
int swr_inject_silence(struct SwrContext *s, int count)
Injects the specified number of silence samples.
#define AV_NOPTS_VALUE
Undefined timestamp value.
AudioData silence
temporary with silence
int resample_first
1 if resampling must come first, 0 if rematrixing
av_cold int swr_init(struct SwrContext *s)
Initialize context after user parameters have been set.