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 */
203  c->buffer = ff_audio_data_alloc(avr->resample_channels, c->padding_size,
204  avr->internal_sample_fmt,
205  "resample buffer");
206  if (!c->buffer)
207  goto error;
208  c->buffer->nb_samples = c->padding_size;
209  c->initial_padding_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:
218  ff_audio_data_free(&c->buffer);
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) {
356  int bps = av_get_bytes_per_sample(c->avr->internal_sample_fmt);
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) {
375  int bps = av_get_bytes_per_sample(c->avr->internal_sample_fmt);
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;
398  c->final_padding_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,
419  c->buffer->nb_samples, dst->allocated_samples,
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);
429  c->initial_padding_samples = FFMAX(c->initial_padding_samples - consumed, 0);
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 }
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
ff_audio_resample_init_aarch64
av_cold void ff_audio_resample_init_aarch64(ResampleContext *c, enum AVSampleFormat sample_fmt)
Definition: resample_init.c:48
AV_RESAMPLE_FILTER_TYPE_KAISER
AV_RESAMPLE_FILTER_TYPE_KAISER
Kaiser Windowed Sinc.
Definition: avresample.h:126
AVAudioResampleContext::filter_size
int filter_size
length of each FIR filter in the resampling filterbank relative to the cutoff frequency
Definition: internal.h:69
AVERROR
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
libm.h
ff_audio_data_alloc
AudioData * ff_audio_data_alloc(int channels, int nb_samples, enum AVSampleFormat sample_fmt, const char *name)
Allocate AudioData.
Definition: audio_data.c:119
ch
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/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_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 *(INT64_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 *(INT64_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
AudioData::data
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:39
w
uint8_t w
Definition: llviddspenc.c:38
bessel
static double bessel(double x)
Definition: resample.c:50
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:68
ff_audio_resample_free
void ff_audio_resample_free(ResampleContext **c)
Free a ResampleContext.
Definition: resample.c:224
ff_audio_data_free
void ff_audio_data_free(AudioData **a)
Free AudioData.
Definition: audio_data.c:217
avresample_get_delay
int avresample_get_delay(AVAudioResampleContext *avr)
Definition: resample.c:438
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
resample.h
AudioData
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
AVAudioResampleContext
Definition: internal.h:53
AVAudioResampleContext::linear_interp
int linear_interp
if 1 then the resampling FIR filter will be linearly interpolated
Definition: internal.h:71
tab
static const struct twinvq_data tab
Definition: twinvq_data.h:11135
AVAudioResampleContext::cutoff
double cutoff
resampling cutoff frequency.
Definition: internal.h:72
av_reduce
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
src
#define src
Definition: vp8dsp.c:254
resample
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
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVAudioResampleContext::filter_type
enum AVResampleFilterType filter_type
resampling filter type
Definition: internal.h:73
ResampleContext
Definition: af_resample.c:38
resample_template.c
avresample_set_compensation
int avresample_set_compensation(AVAudioResampleContext *avr, int sample_delta, int compensation_distance)
Definition: resample.c:233
build_filter
static int build_filter(ResampleContext *c, double factor)
Definition: resample.c:67
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
av_get_sample_fmt_name
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
AudioData::allocated_samples
int allocated_samples
number of samples the buffer can hold
Definition: audio_data.h:42
ff_audio_resample_init
ResampleContext * ff_audio_resample_init(AVAudioResampleContext *avr)
Allocate and initialize a ResampleContext.
Definition: resample.c:120
NULL
#define NULL
Definition: coverity.c:32
internal.h
audio_data.h
index
int index
Definition: gxfenc.c:89
c
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
error
static void error(const char *err)
Definition: target_dec_fuzzer.c:61
ff_audio_resample_init_arm
av_cold void ff_audio_resample_init_arm(ResampleContext *c, enum AVSampleFormat sample_fmt)
Definition: resample_init.c:52
AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL
AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL
Blackman Nuttall Windowed Sinc.
Definition: avresample.h:125
AVAudioResampleContext::resample
ResampleContext * resample
resampling context
Definition: internal.h:95
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
bps
unsigned bps
Definition: movenc.c:1497
AV_RESAMPLE_FILTER_TYPE_CUBIC
AV_RESAMPLE_FILTER_TYPE_CUBIC
Cubic.
Definition: avresample.h:124
AVAudioResampleContext::out_sample_rate
int out_sample_rate
output sample rate
Definition: internal.h:61
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
M_PI
#define M_PI
Definition: mathematics.h:52
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:67
AudioData::allow_realloc
int allow_realloc
realloc is allowed
Definition: audio_data.h:52
AVAudioResampleContext::kaiser_beta
int kaiser_beta
beta value for Kaiser window (only applicable if filter_type == AV_FILTER_TYPE_KAISER)
Definition: internal.h:74
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
AVAudioResampleContext::in_sample_rate
int in_sample_rate
input sample rate
Definition: internal.h:58
common.h
AVAudioResampleContext::resample_needed
int resample_needed
resampling is needed
Definition: internal.h:83
av_mallocz
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
AudioData::read_only
int read_only
data is read-only
Definition: audio_data.h:51
AudioData::nb_samples
int nb_samples
current number of samples
Definition: audio_data.h:43
ret
ret
Definition: filter_design.txt:187
ff_audio_data_realloc
int ff_audio_data_realloc(AudioData *a, int nb_samples)
Reallocate AudioData.
Definition: audio_data.c:162
ff_audio_data_combine
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
AVAudioResampleContext::internal_sample_fmt
enum AVSampleFormat internal_sample_fmt
internal sample format
Definition: internal.h:62
AVAudioResampleContext::phase_shift
int phase_shift
log2 of the number of entries in the resampling polyphase filterbank
Definition: internal.h:70
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
factor
static const int factor[16]
Definition: vf_pp7.c:75
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVAudioResampleContext::resample_channels
int resample_channels
number of channels used for resampling
Definition: internal.h:79
ff_audio_resample
int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src)
Resample audio data.
Definition: resample.c:334
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ff_audio_data_drain
void ff_audio_data_drain(AudioData *a, int nb_samples)
Drain samples from the start of the AudioData.
Definition: audio_data.c:334