FFmpeg
resample.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
3  * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/common.h"
23 #include "libavutil/libm.h"
24 #include "libavutil/log.h"
25 #include "internal.h"
26 #include "resample.h"
27 #include "audio_data.h"
28 
29 
30 /* double template */
31 #define CONFIG_RESAMPLE_DBL
32 #include "resample_template.c"
33 #undef CONFIG_RESAMPLE_DBL
34 
35 /* float template */
36 #define CONFIG_RESAMPLE_FLT
37 #include "resample_template.c"
38 #undef CONFIG_RESAMPLE_FLT
39 
40 /* s32 template */
41 #define CONFIG_RESAMPLE_S32
42 #include "resample_template.c"
43 #undef CONFIG_RESAMPLE_S32
44 
45 /* s16 template */
46 #include "resample_template.c"
47 
48 
49 /* 0th order modified Bessel function of the first kind. */
50 static double bessel(double x)
51 {
52  double v = 1;
53  double lastv = 0;
54  double t = 1;
55  int i;
56 
57  x = x * x / 4;
58  for (i = 1; v != lastv; i++) {
59  lastv = v;
60  t *= x / (i * i);
61  v += t;
62  }
63  return v;
64 }
65 
66 /* Build a polyphase filterbank. */
67 static int build_filter(ResampleContext *c, double factor)
68 {
69  int ph, i;
70  double x, y, w;
71  double *tab;
72  int tap_count = c->filter_length;
73  int phase_count = 1 << c->phase_shift;
74  const int center = (tap_count - 1) / 2;
75 
76  tab = av_malloc(tap_count * sizeof(*tab));
77  if (!tab)
78  return AVERROR(ENOMEM);
79 
80  for (ph = 0; ph < phase_count; ph++) {
81  double norm = 0;
82  for (i = 0; i < tap_count; i++) {
83  x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
84  if (x == 0) y = 1.0;
85  else y = sin(x) / x;
86  switch (c->filter_type) {
88  const float d = -0.5; //first order derivative = -0.5
89  x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
90  if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * ( -x*x + x*x*x);
91  else y = d * (-4 + 8 * x - 5 * x*x + x*x*x);
92  break;
93  }
95  w = 2.0 * x / (factor * tap_count) + M_PI;
96  y *= 0.3635819 - 0.4891775 * cos( w) +
97  0.1365995 * cos(2 * w) -
98  0.0106411 * cos(3 * w);
99  break;
101  w = 2.0 * x / (factor * tap_count * M_PI);
102  y *= bessel(c->kaiser_beta * sqrt(FFMAX(1 - w * w, 0)));
103  break;
104  }
105 
106  tab[i] = y;
107  norm += y;
108  }
109  /* normalize so that an uniform color remains the same */
110  for (i = 0; i < tap_count; i++)
111  tab[i] = tab[i] / norm;
112 
113  c->set_filter(c->filter_bank, tab, ph, tap_count);
114  }
115 
116  av_free(tab);
117  return 0;
118 }
119 
121 {
123  int out_rate = avr->out_sample_rate;
124  int in_rate = avr->in_sample_rate;
125  double factor = FFMIN(out_rate * avr->cutoff / in_rate, 1.0);
126  int phase_count = 1 << avr->phase_shift;
127  int felem_size;
128 
133  av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
134  "resampling: %s\n",
136  return NULL;
137  }
138  c = av_mallocz(sizeof(*c));
139  if (!c)
140  return NULL;
141 
142  c->avr = avr;
143  c->phase_shift = avr->phase_shift;
144  c->phase_mask = phase_count - 1;
145  c->linear = avr->linear_interp;
146  c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
147  c->filter_type = avr->filter_type;
148  c->kaiser_beta = avr->kaiser_beta;
149 
150  switch (avr->internal_sample_fmt) {
151  case AV_SAMPLE_FMT_DBLP:
152  c->resample_one = c->linear ? resample_linear_dbl : resample_one_dbl;
153  c->resample_nearest = resample_nearest_dbl;
154  c->set_filter = set_filter_dbl;
155  break;
156  case AV_SAMPLE_FMT_FLTP:
157  c->resample_one = c->linear ? resample_linear_flt : resample_one_flt;
158  c->resample_nearest = resample_nearest_flt;
159  c->set_filter = set_filter_flt;
160  break;
161  case AV_SAMPLE_FMT_S32P:
162  c->resample_one = c->linear ? resample_linear_s32 : resample_one_s32;
163  c->resample_nearest = resample_nearest_s32;
164  c->set_filter = set_filter_s32;
165  break;
166  case AV_SAMPLE_FMT_S16P:
167  c->resample_one = c->linear ? resample_linear_s16 : resample_one_s16;
168  c->resample_nearest = resample_nearest_s16;
169  c->set_filter = set_filter_s16;
170  break;
171  }
172 
173  if (ARCH_AARCH64)
175  if (ARCH_ARM)
177 
178  felem_size = av_get_bytes_per_sample(avr->internal_sample_fmt);
179  c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * felem_size);
180  if (!c->filter_bank)
181  goto error;
182 
183  if (build_filter(c, factor) < 0)
184  goto error;
185 
186  memcpy(&c->filter_bank[(c->filter_length * phase_count + 1) * felem_size],
187  c->filter_bank, (c->filter_length - 1) * felem_size);
188  memcpy(&c->filter_bank[c->filter_length * phase_count * felem_size],
189  &c->filter_bank[(c->filter_length - 1) * felem_size], felem_size);
190 
191  c->compensation_distance = 0;
192  if (!av_reduce(&c->src_incr, &c->dst_incr, out_rate,
193  in_rate * (int64_t)phase_count, INT32_MAX / 2))
194  goto error;
195  c->ideal_dst_incr = c->dst_incr;
196 
197  c->padding_size = (c->filter_length - 1) / 2;
198  c->initial_padding_filled = 0;
199  c->index = 0;
200  c->frac = 0;
201 
202  /* allocate internal buffer */
204  avr->internal_sample_fmt,
205  "resample buffer");
206  if (!c->buffer)
207  goto error;
208  c->buffer->nb_samples = c->padding_size;
210 
211  av_log(avr, AV_LOG_DEBUG, "resample: %s from %d Hz to %d Hz\n",
213  avr->in_sample_rate, avr->out_sample_rate);
214 
215  return c;
216 
217 error:
219  av_free(c->filter_bank);
220  av_free(c);
221  return NULL;
222 }
223 
225 {
226  if (!*c)
227  return;
228  ff_audio_data_free(&(*c)->buffer);
229  av_free((*c)->filter_bank);
230  av_freep(c);
231 }
232 
234  int compensation_distance)
235 {
237 
238  if (compensation_distance < 0)
239  return AVERROR(EINVAL);
240  if (!compensation_distance && sample_delta)
241  return AVERROR(EINVAL);
242 
243  if (!avr->resample_needed) {
244  av_log(avr, AV_LOG_ERROR, "Unable to set resampling compensation\n");
245  return AVERROR(EINVAL);
246  }
247  c = avr->resample;
248  c->compensation_distance = compensation_distance;
249  if (compensation_distance) {
250  c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr *
251  (int64_t)sample_delta / compensation_distance;
252  } else {
253  c->dst_incr = c->ideal_dst_incr;
254  }
255 
256  return 0;
257 }
258 
259 static int resample(ResampleContext *c, void *dst, const void *src,
260  int *consumed, int src_size, int dst_size, int update_ctx,
261  int nearest_neighbour)
262 {
263  int dst_index;
264  unsigned int index = c->index;
265  int frac = c->frac;
266  int dst_incr_frac = c->dst_incr % c->src_incr;
267  int dst_incr = c->dst_incr / c->src_incr;
268  int compensation_distance = c->compensation_distance;
269 
270  if (!dst != !src)
271  return AVERROR(EINVAL);
272 
273  if (nearest_neighbour) {
274  uint64_t index2 = ((uint64_t)index) << 32;
275  int64_t incr = (1LL << 32) * c->dst_incr / c->src_incr;
276  dst_size = FFMIN(dst_size,
277  (src_size-1-index) * (int64_t)c->src_incr /
278  c->dst_incr);
279 
280  if (dst) {
281  for(dst_index = 0; dst_index < dst_size; dst_index++) {
282  c->resample_nearest(dst, dst_index, src, index2 >> 32);
283  index2 += incr;
284  }
285  } else {
286  dst_index = dst_size;
287  }
288  index += dst_index * dst_incr;
289  index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
290  frac = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
291  } else {
292  for (dst_index = 0; dst_index < dst_size; dst_index++) {
293  int sample_index = index >> c->phase_shift;
294 
295  if (sample_index + c->filter_length > src_size)
296  break;
297 
298  if (dst)
299  c->resample_one(c, dst, dst_index, src, index, frac);
300 
301  frac += dst_incr_frac;
302  index += dst_incr;
303  if (frac >= c->src_incr) {
304  frac -= c->src_incr;
305  index++;
306  }
307  if (dst_index + 1 == compensation_distance) {
308  compensation_distance = 0;
309  dst_incr_frac = c->ideal_dst_incr % c->src_incr;
310  dst_incr = c->ideal_dst_incr / c->src_incr;
311  }
312  }
313  }
314  if (consumed)
315  *consumed = index >> c->phase_shift;
316 
317  if (update_ctx) {
318  index &= c->phase_mask;
319 
320  if (compensation_distance) {
321  compensation_distance -= dst_index;
322  if (compensation_distance <= 0)
323  return AVERROR_BUG;
324  }
325  c->frac = frac;
326  c->index = index;
327  c->dst_incr = dst_incr_frac + c->src_incr*dst_incr;
328  c->compensation_distance = compensation_distance;
329  }
330 
331  return dst_index;
332 }
333 
335 {
336  int ch, in_samples, in_leftover, consumed = 0, out_samples = 0;
337  int ret = AVERROR(EINVAL);
338  int nearest_neighbour = (c->compensation_distance == 0 &&
339  c->filter_length == 1 &&
340  c->phase_shift == 0);
341 
342  in_samples = src ? src->nb_samples : 0;
343  in_leftover = c->buffer->nb_samples;
344 
345  /* add input samples to the internal buffer */
346  if (src) {
347  ret = ff_audio_data_combine(c->buffer, in_leftover, src, 0, in_samples);
348  if (ret < 0)
349  return ret;
350  } else if (in_leftover <= c->final_padding_samples) {
351  /* no remaining samples to flush */
352  return 0;
353  }
354 
355  if (!c->initial_padding_filled) {
357  int i;
358 
359  if (src && c->buffer->nb_samples < 2 * c->padding_size)
360  return 0;
361 
362  for (i = 0; i < c->padding_size; i++)
363  for (ch = 0; ch < c->buffer->channels; ch++) {
364  if (c->buffer->nb_samples > 2 * c->padding_size - i) {
365  memcpy(c->buffer->data[ch] + bps * i,
366  c->buffer->data[ch] + bps * (2 * c->padding_size - i), bps);
367  } else {
368  memset(c->buffer->data[ch] + bps * i, 0, bps);
369  }
370  }
371  c->initial_padding_filled = 1;
372  }
373 
374  if (!src && !c->final_padding_filled) {
376  int i;
377 
378  ret = ff_audio_data_realloc(c->buffer,
379  FFMAX(in_samples, in_leftover) +
380  c->padding_size);
381  if (ret < 0) {
382  av_log(c->avr, AV_LOG_ERROR, "Error reallocating resampling buffer\n");
383  return AVERROR(ENOMEM);
384  }
385 
386  for (i = 0; i < c->padding_size; i++)
387  for (ch = 0; ch < c->buffer->channels; ch++) {
388  if (in_leftover > i) {
389  memcpy(c->buffer->data[ch] + bps * (in_leftover + i),
390  c->buffer->data[ch] + bps * (in_leftover - i - 1),
391  bps);
392  } else {
393  memset(c->buffer->data[ch] + bps * (in_leftover + i),
394  0, bps);
395  }
396  }
397  c->buffer->nb_samples += c->padding_size;
399  c->final_padding_filled = 1;
400  }
401 
402 
403  /* calculate output size and reallocate output buffer if needed */
404  /* TODO: try to calculate this without the dummy resample() run */
405  if (!dst->read_only && dst->allow_realloc) {
406  out_samples = resample(c, NULL, NULL, NULL, c->buffer->nb_samples,
407  INT_MAX, 0, nearest_neighbour);
408  ret = ff_audio_data_realloc(dst, out_samples);
409  if (ret < 0) {
410  av_log(c->avr, AV_LOG_ERROR, "error reallocating output\n");
411  return ret;
412  }
413  }
414 
415  /* resample each channel plane */
416  for (ch = 0; ch < c->buffer->channels; ch++) {
417  out_samples = resample(c, (void *)dst->data[ch],
418  (const void *)c->buffer->data[ch], &consumed,
420  ch + 1 == c->buffer->channels, nearest_neighbour);
421  }
422  if (out_samples < 0) {
423  av_log(c->avr, AV_LOG_ERROR, "error during resampling\n");
424  return out_samples;
425  }
426 
427  /* drain consumed samples from the internal buffer */
428  ff_audio_data_drain(c->buffer, consumed);
430 
431  av_log(c->avr, AV_LOG_TRACE, "resampled %d in + %d leftover to %d out + %d leftover\n",
432  in_samples, in_leftover, out_samples, c->buffer->nb_samples);
433 
434  dst->nb_samples = out_samples;
435  return 0;
436 }
437 
439 {
440  ResampleContext *c = avr->resample;
441 
442  if (!avr->resample_needed || !avr->resample)
443  return 0;
444 
445  return FFMAX(c->buffer->nb_samples - c->padding_size, 0);
446 }
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
int initial_padding_filled
Definition: resample.h:51
int initial_padding_samples
Definition: resample.h:52
int padding_size
Definition: resample.h:50
int avresample_set_compensation(AVAudioResampleContext *avr, int sample_delta, int compensation_distance)
Definition: resample.c:233
int ff_audio_data_realloc(AudioData *a, int nb_samples)
Reallocate AudioData.
Definition: audio_data.c:162
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
int avresample_get_delay(AVAudioResampleContext *avr)
Definition: resample.c:438
AudioData * ff_audio_data_alloc(int channels, int nb_samples, enum AVSampleFormat sample_fmt, const char *name)
Allocate AudioData.
Definition: audio_data.c:119
int allow_realloc
realloc is allowed
Definition: audio_data.h:52
double, planar
Definition: samplefmt.h:70
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
#define src
Definition: vp8dsp.c:254
double cutoff
resampling cutoff frequency.
Definition: internal.h:72
int nb_samples
current number of samples
Definition: audio_data.h:43
static int resample(ResampleContext *c, void *dst, const void *src, int *consumed, int src_size, int dst_size, int update_ctx, int nearest_neighbour)
Definition: resample.c:259
AudioData * buffer
Definition: resample.h:30
#define av_malloc(s)
AVAudioResampleContext * avr
Definition: af_resample.c:40
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
int read_only
data is read-only
Definition: audio_data.h:51
int compensation_distance
Definition: resample.h:38
enum AVResampleFilterType filter_type
Definition: resample.h:42
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
#define av_log(a,...)
int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src)
Resample audio data.
Definition: resample.c:334
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int channels
channel count
Definition: audio_data.h:45
unsigned int index
Definition: resample.h:35
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition: samplefmt.c:49
#define FFMAX(a, b)
Definition: common.h:94
AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL
Blackman Nuttall Windowed Sinc.
Definition: avresample.h:124
ResampleContext * resample
resampling context
Definition: internal.h:95
av_cold void ff_audio_resample_init_arm(ResampleContext *c, enum AVSampleFormat sample_fmt)
Definition: resample_init.c:52
#define FFMIN(a, b)
Definition: common.h:96
signed 32 bits, planar
Definition: samplefmt.h:68
int phase_shift
log2 of the number of entries in the resampling polyphase filterbank
Definition: internal.h:70
uint8_t w
Definition: llviddspenc.c:38
int ff_audio_data_combine(AudioData *dst, int dst_offset, AudioData *src, int src_offset, int nb_samples)
Append data from one AudioData to the end of another.
Definition: audio_data.c:278
void ff_audio_data_drain(AudioData *a, int nb_samples)
Drain samples from the start of the AudioData.
Definition: audio_data.c:334
int linear_interp
if 1 then the resampling FIR filter will be linearly interpolated
Definition: internal.h:71
int kaiser_beta
beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER) ...
Definition: internal.h:74
void(* set_filter)(void *filter, double *tab, int phase, int tap_count)
Definition: resample.h:44
static void error(const char *err)
int in_sample_rate
input sample rate
Definition: internal.h:58
void ff_audio_resample_free(ResampleContext **c)
Free a ResampleContext.
Definition: resample.c:224
static int build_filter(ResampleContext *c, double factor)
Definition: resample.c:67
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:39
enum AVResampleFilterType filter_type
resampling filter type
Definition: internal.h:73
enum AVSampleFormat internal_sample_fmt
internal sample format
Definition: internal.h:62
void(* resample_nearest)(void *dst0, int dst_index, const void *src0, unsigned int index)
Definition: resample.h:48
Replacements for frequently missing libm functions.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
int filter_length
Definition: resample.h:32
ResampleContext * ff_audio_resample_init(AVAudioResampleContext *avr)
Allocate and initialize a ResampleContext.
Definition: resample.c:120
int index
Definition: gxfenc.c:89
int filter_size
length of each FIR filter in the resampling filterbank relative to the cutoff frequency ...
Definition: internal.h:69
AV_RESAMPLE_FILTER_TYPE_CUBIC
Cubic.
Definition: avresample.h:124
static const int factor[16]
Definition: vf_pp7.c:75
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63)))#define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};static void cpy1(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, len);}static void cpy2(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 2 *len);}static void cpy4(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 4 *len);}static void cpy8(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;}void swri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len){int ch;int off=0;const int os=(out->planar?1:out->ch_count)*out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){int planes=in->planar?in->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){int planes=out->planar?out->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){int planes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
int final_padding_filled
Definition: resample.h:53
int ideal_dst_incr
Definition: resample.h:33
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
common internal and external API header
int resample_channels
number of channels used for resampling
Definition: internal.h:79
int resample_needed
resampling is needed
Definition: internal.h:83
unsigned bps
Definition: movenc.c:1532
void(* resample_one)(struct ResampleContext *c, void *dst0, int dst_index, const void *src0, unsigned int index, int frac)
Definition: resample.h:45
#define av_free(p)
int final_padding_samples
Definition: resample.h:54
int allocated_samples
number of samples the buffer can hold
Definition: audio_data.h:42
AV_RESAMPLE_FILTER_TYPE_KAISER
Kaiser Windowed Sinc.
Definition: avresample.h:124
uint8_t * filter_bank
Definition: resample.h:31
static const struct twinvq_data tab
#define av_freep(p)
int out_sample_rate
output sample rate
Definition: internal.h:61
void ff_audio_data_free(AudioData **a)
Free AudioData.
Definition: audio_data.c:217
signed 16 bits, planar
Definition: samplefmt.h:67
#define M_PI
Definition: mathematics.h:52
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
static double bessel(double x)
Definition: resample.c:50
av_cold void ff_audio_resample_init_aarch64(ResampleContext *c, enum AVSampleFormat sample_fmt)
Definition: resample_init.c:48