FFmpeg
audio_convert.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 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 <stdint.h>
23 
24 #include "config.h"
25 #include "libavutil/common.h"
26 #include "libavutil/libm.h"
27 #include "libavutil/log.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/samplefmt.h"
30 #include "audio_convert.h"
31 #include "audio_data.h"
32 #include "dither.h"
33 
38 };
39 
40 typedef void (conv_func_flat)(uint8_t *out, const uint8_t *in, int len);
41 
43  int len, int channels);
44 
45 typedef void (conv_func_deinterleave)(uint8_t **out, const uint8_t *in, int len,
46  int channels);
47 
48 struct AudioConvert {
53  int apply_map;
54  int channels;
55  int planes;
56  int ptr_align;
59  const char *func_descr;
60  const char *func_descr_generic;
68 };
69 
71  enum AVSampleFormat in_fmt, int channels,
72  int ptr_align, int samples_align,
73  const char *descr, void *conv)
74 {
75  int found = 0;
76 
77  switch (ac->func_type) {
79  if (av_get_packed_sample_fmt(ac->in_fmt) == in_fmt &&
80  av_get_packed_sample_fmt(ac->out_fmt) == out_fmt) {
81  ac->conv_flat = conv;
82  ac->func_descr = descr;
83  ac->ptr_align = ptr_align;
85  if (ptr_align == 1 && samples_align == 1) {
86  ac->conv_flat_generic = conv;
87  ac->func_descr_generic = descr;
88  } else {
89  ac->has_optimized_func = 1;
90  }
91  found = 1;
92  }
93  break;
95  if (ac->in_fmt == in_fmt && ac->out_fmt == out_fmt &&
96  (!channels || ac->channels == channels)) {
97  ac->conv_interleave = conv;
98  ac->func_descr = descr;
99  ac->ptr_align = ptr_align;
101  if (ptr_align == 1 && samples_align == 1) {
103  ac->func_descr_generic = descr;
104  } else {
105  ac->has_optimized_func = 1;
106  }
107  found = 1;
108  }
109  break;
111  if (ac->in_fmt == in_fmt && ac->out_fmt == out_fmt &&
112  (!channels || ac->channels == channels)) {
113  ac->conv_deinterleave = conv;
114  ac->func_descr = descr;
115  ac->ptr_align = ptr_align;
117  if (ptr_align == 1 && samples_align == 1) {
119  ac->func_descr_generic = descr;
120  } else {
121  ac->has_optimized_func = 1;
122  }
123  found = 1;
124  }
125  break;
126  }
127  if (found) {
128  av_log(ac->avr, AV_LOG_DEBUG, "audio_convert: found function: %-4s "
129  "to %-4s (%s)\n", av_get_sample_fmt_name(ac->in_fmt),
130  av_get_sample_fmt_name(ac->out_fmt), descr);
131  }
132 }
133 
134 #define CONV_FUNC_NAME(dst_fmt, src_fmt) conv_ ## src_fmt ## _to_ ## dst_fmt
135 
136 #define CONV_LOOP(otype, expr) \
137  do { \
138  *(otype *)po = expr; \
139  pi += is; \
140  po += os; \
141  } while (po < end); \
142 
143 #define CONV_FUNC_FLAT(ofmt, otype, ifmt, itype, expr) \
144 static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *out, const uint8_t *in, \
145  int len) \
146 { \
147  int is = sizeof(itype); \
148  int os = sizeof(otype); \
149  const uint8_t *pi = in; \
150  uint8_t *po = out; \
151  uint8_t *end = out + os * len; \
152  CONV_LOOP(otype, expr) \
153 }
154 
155 #define CONV_FUNC_INTERLEAVE(ofmt, otype, ifmt, itype, expr) \
156 static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *out, const uint8_t **in, \
157  int len, int channels) \
158 { \
159  int ch; \
160  int out_bps = sizeof(otype); \
161  int is = sizeof(itype); \
162  int os = channels * out_bps; \
163  for (ch = 0; ch < channels; ch++) { \
164  const uint8_t *pi = in[ch]; \
165  uint8_t *po = out + ch * out_bps; \
166  uint8_t *end = po + os * len; \
167  CONV_LOOP(otype, expr) \
168  } \
169 }
170 
171 #define CONV_FUNC_DEINTERLEAVE(ofmt, otype, ifmt, itype, expr) \
172 static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t **out, const uint8_t *in, \
173  int len, int channels) \
174 { \
175  int ch; \
176  int in_bps = sizeof(itype); \
177  int is = channels * in_bps; \
178  int os = sizeof(otype); \
179  for (ch = 0; ch < channels; ch++) { \
180  const uint8_t *pi = in + ch * in_bps; \
181  uint8_t *po = out[ch]; \
182  uint8_t *end = po + os * len; \
183  CONV_LOOP(otype, expr) \
184  } \
185 }
186 
187 #define CONV_FUNC_GROUP(ofmt, otype, ifmt, itype, expr) \
188 CONV_FUNC_FLAT( ofmt, otype, ifmt, itype, expr) \
189 CONV_FUNC_INTERLEAVE( ofmt, otype, ifmt ## P, itype, expr) \
190 CONV_FUNC_DEINTERLEAVE(ofmt ## P, otype, ifmt, itype, expr)
191 
193 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) << 8)
194 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) << 24)
195 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) * (1.0f / (1 << 7)))
196 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) * (1.0 / (1 << 7)))
197 CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t, (*(const int16_t *)pi >> 8) + 0x80)
198 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi)
199 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi << 16)
200 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi * (1.0f / (1 << 15)))
201 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi * (1.0 / (1 << 15)))
202 CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t, (*(const int32_t *)pi >> 24) + 0x80)
203 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi >> 16)
204 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi)
205 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi * (1.0f / (1U << 31)))
206 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi * (1.0 / (1U << 31)))
207 CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8( lrintf(*(const float *)pi * (1 << 7)) + 0x80))
208 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16( lrintf(*(const float *)pi * (1 << 15))))
209 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *)pi * (1U << 31))))
210 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_FLT, float, *(const float *)pi)
211 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_FLT, float, *(const float *)pi)
212 CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8( lrint(*(const double *)pi * (1 << 7)) + 0x80))
213 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16( lrint(*(const double *)pi * (1 << 15))))
214 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *)pi * (1U << 31))))
215 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_DBL, double, *(const double *)pi)
216 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_DBL, double, *(const double *)pi)
217 
218 #define SET_CONV_FUNC_GROUP(ofmt, ifmt) \
219 ff_audio_convert_set_func(ac, ofmt, ifmt, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt, ifmt)); \
220 ff_audio_convert_set_func(ac, ofmt ## P, ifmt, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt ## P, ifmt)); \
221 ff_audio_convert_set_func(ac, ofmt, ifmt ## P, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt, ifmt ## P));
222 
223 static void set_generic_function(AudioConvert *ac)
224 {
225  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8)
226  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8)
227  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8)
228  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8)
229  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8)
230  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16)
231  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16)
232  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16)
233  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16)
234  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16)
235  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32)
236  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32)
237  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32)
238  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32)
239  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32)
240  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT)
241  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT)
242  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT)
243  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT)
244  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT)
245  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL)
246  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL)
247  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL)
248  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL)
249  SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL)
250 }
251 
253 {
254  if (!*ac)
255  return;
256  ff_dither_free(&(*ac)->dc);
257  av_freep(ac);
258 }
259 
261  enum AVSampleFormat out_fmt,
262  enum AVSampleFormat in_fmt,
263  int channels, int sample_rate,
264  int apply_map)
265 {
266  AudioConvert *ac;
267  int in_planar, out_planar;
268 
269  ac = av_mallocz(sizeof(*ac));
270  if (!ac)
271  return NULL;
272 
273  ac->avr = avr;
274  ac->out_fmt = out_fmt;
275  ac->in_fmt = in_fmt;
276  ac->channels = channels;
277  ac->apply_map = apply_map;
278 
280  av_get_packed_sample_fmt(out_fmt) == AV_SAMPLE_FMT_S16 &&
281  av_get_bytes_per_sample(in_fmt) > 2) {
282  ac->dc = ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate,
283  apply_map);
284  if (!ac->dc) {
285  av_free(ac);
286  return NULL;
287  }
288  return ac;
289  }
290 
291  in_planar = ff_sample_fmt_is_planar(in_fmt, channels);
292  out_planar = ff_sample_fmt_is_planar(out_fmt, channels);
293 
294  if (in_planar == out_planar) {
296  ac->planes = in_planar ? ac->channels : 1;
297  } else if (in_planar)
299  else
301 
302  set_generic_function(ac);
303 
304  if (ARCH_AARCH64)
306  if (ARCH_ARM)
308  if (ARCH_X86)
310 
311  return ac;
312 }
313 
315 {
316  int use_generic = 1;
317  int len = in->nb_samples;
318  int p;
319 
320  if (ac->dc) {
321  /* dithered conversion */
322  av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n",
323  len, av_get_sample_fmt_name(ac->in_fmt),
325 
326  return ff_convert_dither(ac->dc, out, in);
327  }
328 
329  /* determine whether to use the optimized function based on pointer and
330  samples alignment in both the input and output */
332  int ptr_align = FFMIN(in->ptr_align, out->ptr_align);
334  int aligned_len = FFALIGN(len, ac->samples_align);
335  if (!(ptr_align % ac->ptr_align) && samples_align >= aligned_len) {
336  len = aligned_len;
337  use_generic = 0;
338  }
339  }
340  av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\n", len,
343  use_generic ? ac->func_descr_generic : ac->func_descr);
344 
345  if (ac->apply_map) {
347 
348  if (!ff_sample_fmt_is_planar(ac->out_fmt, ac->channels)) {
349  av_log(ac->avr, AV_LOG_ERROR, "cannot remap packed format during conversion\n");
350  return AVERROR(EINVAL);
351  }
352 
353  if (map->do_remap) {
354  if (ff_sample_fmt_is_planar(ac->in_fmt, ac->channels)) {
355  conv_func_flat *convert = use_generic ? ac->conv_flat_generic :
356  ac->conv_flat;
357 
358  for (p = 0; p < ac->planes; p++)
359  if (map->channel_map[p] >= 0)
360  convert(out->data[p], in->data[map->channel_map[p]], len);
361  } else {
362  uint8_t *data[AVRESAMPLE_MAX_CHANNELS];
363  conv_func_deinterleave *convert = use_generic ?
365  ac->conv_deinterleave;
366 
367  for (p = 0; p < ac->channels; p++)
368  data[map->input_map[p]] = out->data[p];
369 
370  convert(data, in->data[0], len, ac->channels);
371  }
372  }
373  if (map->do_copy || map->do_zero) {
374  for (p = 0; p < ac->planes; p++) {
375  if (map->channel_copy[p])
376  memcpy(out->data[p], out->data[map->channel_copy[p]],
377  len * out->stride);
378  else if (map->channel_zero[p])
379  av_samples_set_silence(&out->data[p], 0, len, 1, ac->out_fmt);
380  }
381  }
382  } else {
383  switch (ac->func_type) {
384  case CONV_FUNC_TYPE_FLAT: {
385  if (!in->is_planar)
386  len *= in->channels;
387  if (use_generic) {
388  for (p = 0; p < ac->planes; p++)
389  ac->conv_flat_generic(out->data[p], in->data[p], len);
390  } else {
391  for (p = 0; p < ac->planes; p++)
392  ac->conv_flat(out->data[p], in->data[p], len);
393  }
394  break;
395  }
397  if (use_generic)
398  ac->conv_interleave_generic(out->data[0], in->data, len,
399  ac->channels);
400  else
401  ac->conv_interleave(out->data[0], in->data, len, ac->channels);
402  break;
404  if (use_generic)
405  ac->conv_deinterleave_generic(out->data, in->data[0], len,
406  ac->channels);
407  else
408  ac->conv_deinterleave(out->data, in->data[0], len,
409  ac->channels);
410  break;
411  }
412  }
413 
414  out->nb_samples = in->nb_samples;
415  return 0;
416 }
AVAudioResampleContext * avr
Definition: audio_convert.c:49
#define NULL
Definition: coverity.c:32
void ff_dither_free(DitherContext **cp)
Free a DitherContext.
Definition: dither.c:312
void( conv_func_deinterleave)(uint8_t **out, const uint8_t *in, int len, int channels)
Definition: audio_convert.c:45
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static int conv(int samples, float **pcm, char *buf, int channels)
Definition: libvorbisdec.c:131
int input_map[AVRESAMPLE_MAX_CHANNELS]
dest index of each input channel
Definition: internal.h:50
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
conv_func_deinterleave * conv_deinterleave
Definition: audio_convert.c:66
Memory handling functions.
DitherContext * dc
Definition: audio_convert.c:50
int do_zero
zeroing needed
Definition: internal.h:49
channels
Definition: aptx.c:30
int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
Convert audio data from one sample format to another.
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
void ff_audio_convert_init_x86(AudioConvert *ac)
int channel_zero[AVRESAMPLE_MAX_CHANNELS]
dest index to zero
Definition: internal.h:48
int nb_samples
current number of samples
Definition: audio_data.h:43
conv_func_interleave * conv_interleave
Definition: audio_convert.c:64
uint8_t
AV_SAMPLE_FMT_U8
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
#define f(width, name)
Definition: cbs_vp9.c:255
int ff_sample_fmt_is_planar(enum AVSampleFormat sample_fmt, int channels)
Definition: audio_data.c:51
#define llrintf(x)
Definition: libm.h:399
#define lrintf(x)
Definition: libm_mips.h:70
signed 32 bits
Definition: samplefmt.h:62
AudioConvert * ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map)
Allocate and initialize AudioConvert context for sample format conversion.
#define FFALIGN(x, a)
Definition: macros.h:48
AV_RESAMPLE_DITHER_NONE
Do not use dithering.
Definition: avresample.h:133
#define U(x)
Definition: vp56_arith.h:37
enum AVResampleDitherMethod dither_method
dither method
Definition: internal.h:75
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition: samplefmt.c:237
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
int stride
sample byte offset within a plane
Definition: audio_data.h:50
int channels
channel count
Definition: audio_data.h:45
av_cold void ff_audio_convert_init_arm(AudioConvert *ac)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
void ff_audio_convert_free(AudioConvert **ac)
Free AudioConvert.
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
DitherContext * ff_dither_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map)
Allocate and initialize a DitherContext.
Definition: dither.c:345
int is_planar
sample format is planar
Definition: audio_data.h:47
int channel_copy[AVRESAMPLE_MAX_CHANNELS]
dest index to copy from
Definition: internal.h:46
#define SET_CONV_FUNC_GROUP(ofmt, ifmt)
int has_optimized_func
Definition: audio_convert.c:58
conv_func_flat * conv_flat
Definition: audio_convert.c:62
#define FFMIN(a, b)
Definition: common.h:96
int do_remap
remap needed
Definition: internal.h:45
int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src)
Convert audio sample format with dithering.
Definition: dither.c:242
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
int32_t
static int convert(uint8_t x)
Definition: xbmdec.c:29
#define CONV_FUNC_GROUP(ofmt, otype, ifmt, itype, expr)
conv_func_interleave * conv_interleave_generic
Definition: audio_convert.c:65
ChannelMapInfo ch_map_info
Definition: internal.h:107
sample_rate
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
const char * func_descr
Definition: audio_convert.c:59
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:39
void( conv_func_interleave)(uint8_t *out, uint8_t *const *in, int len, int channels)
Definition: audio_convert.c:42
#define AVRESAMPLE_MAX_CHANNELS
Definition: avresample.h:104
#define llrint(x)
Definition: libm.h:394
Replacements for frequently missing libm functions.
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
const VDPAUPixFmtMap * map
conv_func_flat * conv_flat_generic
Definition: audio_convert.c:63
int channel_map[AVRESAMPLE_MAX_CHANNELS]
source index of each output channel, -1 if not remapped
Definition: internal.h:44
ConvFuncType
Definition: audio_convert.c:34
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
int samples_align
allocated samples alignment
Definition: audio_data.h:54
av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
const char * func_descr_generic
Definition: audio_convert.c:60
common internal and external API header
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition: samplefmt.c:75
signed 16 bits
Definition: samplefmt.h:61
int do_copy
copy needed
Definition: internal.h:47
#define av_free(p)
int len
enum ConvFuncType func_type
Definition: audio_convert.c:61
#define lrint
Definition: tablegen.h:53
enum AVSampleFormat out_fmt
Definition: audio_convert.c:52
conv_func_deinterleave * conv_deinterleave_generic
Definition: audio_convert.c:67
void ff_audio_convert_set_func(AudioConvert *ac, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int ptr_align, int samples_align, const char *descr, void *conv)
Set conversion function if the parameters match.
Definition: audio_convert.c:70
void( conv_func_flat)(uint8_t *out, const uint8_t *in, int len)
Definition: audio_convert.c:40
enum AVSampleFormat in_fmt
Definition: audio_convert.c:51
av_cold void ff_audio_convert_init_aarch64(AudioConvert *ac)
#define av_freep(p)
int ptr_align
minimum data pointer alignment
Definition: audio_data.h:53
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