FFmpeg  4.3
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 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:29
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
AudioData::data
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:39
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
ARCH_ARM
#define ARCH_ARM
Definition: config.h:19
x
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo x
Definition: fate.txt:150
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
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_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:237
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
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/(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 &&HAVE_MMX) 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::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
src
#define src
Definition: vp8dsp.c:254
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
ff_audio_resample_init_arm
av_cold void ff_audio_resample_init_arm(ResampleContext *c, enum AVSampleFormat sample_fmt)
Definition: resample_init.c:52
ARCH_AARCH64
#define ARCH_AARCH64
Definition: config.h:17
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:1533
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:269
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
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
w
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo ug o o w
Definition: fate.txt:150
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