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 Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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 = av_sample_fmt_is_planar(in_fmt);
292  out_planar = av_sample_fmt_is_planar(out_fmt);
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_ARM)
306  if (ARCH_X86)
308 
309  return ac;
310 }
311 
313 {
314  int use_generic = 1;
315  int len = in->nb_samples;
316  int p;
317 
318  if (ac->dc) {
319  /* dithered conversion */
320  av_dlog(ac->avr, "%d samples - audio_convert: %s to %s (dithered)\n",
321  len, av_get_sample_fmt_name(ac->in_fmt),
323 
324  return ff_convert_dither(ac->dc, out, in);
325  }
326 
327  /* determine whether to use the optimized function based on pointer and
328  samples alignment in both the input and output */
330  int ptr_align = FFMIN(in->ptr_align, out->ptr_align);
332  int aligned_len = FFALIGN(len, ac->samples_align);
333  if (!(ptr_align % ac->ptr_align) && samples_align >= aligned_len) {
334  len = aligned_len;
335  use_generic = 0;
336  }
337  }
338  av_dlog(ac->avr, "%d samples - audio_convert: %s to %s (%s)\n", len,
341  use_generic ? ac->func_descr_generic : ac->func_descr);
342 
343  if (ac->apply_map) {
344  ChannelMapInfo *map = &ac->avr->ch_map_info;
345 
346  if (!av_sample_fmt_is_planar(ac->out_fmt)) {
347  av_log(ac->avr, AV_LOG_ERROR, "cannot remap packed format during conversion\n");
348  return AVERROR(EINVAL);
349  }
350 
351  if (map->do_remap) {
352  if (av_sample_fmt_is_planar(ac->in_fmt)) {
353  conv_func_flat *convert = use_generic ? ac->conv_flat_generic :
354  ac->conv_flat;
355 
356  for (p = 0; p < ac->planes; p++)
357  if (map->channel_map[p] >= 0)
358  convert(out->data[p], in->data[map->channel_map[p]], len);
359  } else {
360  uint8_t *data[AVRESAMPLE_MAX_CHANNELS];
361  conv_func_deinterleave *convert = use_generic ?
363  ac->conv_deinterleave;
364 
365  for (p = 0; p < ac->channels; p++)
366  data[map->input_map[p]] = out->data[p];
367 
368  convert(data, in->data[0], len, ac->channels);
369  }
370  }
371  if (map->do_copy || map->do_zero) {
372  for (p = 0; p < ac->planes; p++) {
373  if (map->channel_copy[p])
374  memcpy(out->data[p], out->data[map->channel_copy[p]],
375  len * out->stride);
376  else if (map->channel_zero[p])
377  av_samples_set_silence(&out->data[p], 0, len, 1, ac->out_fmt);
378  }
379  }
380  } else {
381  switch (ac->func_type) {
382  case CONV_FUNC_TYPE_FLAT: {
383  if (!in->is_planar)
384  len *= in->channels;
385  if (use_generic) {
386  for (p = 0; p < ac->planes; p++)
387  ac->conv_flat_generic(out->data[p], in->data[p], len);
388  } else {
389  for (p = 0; p < ac->planes; p++)
390  ac->conv_flat(out->data[p], in->data[p], len);
391  }
392  break;
393  }
395  if (use_generic)
396  ac->conv_interleave_generic(out->data[0], in->data, len,
397  ac->channels);
398  else
399  ac->conv_interleave(out->data[0], in->data, len, ac->channels);
400  break;
402  if (use_generic)
403  ac->conv_deinterleave_generic(out->data, in->data[0], len,
404  ac->channels);
405  else
406  ac->conv_deinterleave(out->data, in->data[0], len,
407  ac->channels);
408  break;
409  }
410  }
411 
412  out->nb_samples = in->nb_samples;
413  return 0;
414 }
AVAudioResampleContext * avr
Definition: audio_convert.c:49
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
void ff_dither_free(DitherContext **cp)
Free a DitherContext.
void( conv_func_deinterleave)(uint8_t **out, const uint8_t *in, int len, int channels)
Definition: audio_convert.c:45
static int conv(int samples, float **pcm, char *buf, int channels)
Definition: libvorbisdec.c:111
int input_map[AVRESAMPLE_MAX_CHANNELS]
dest index of each input channel
Audio buffer used for intermediate storage between conversion phases.
Definition: oss_audio.c:46
conv_func_deinterleave * conv_deinterleave
Definition: audio_convert.c:66
memory handling functions
DitherContext * dc
Definition: audio_convert.c:50
Do not use dithering.
Definition: avresample.h:123
int do_zero
zeroing needed
Sinusoidal phase f
int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
Convert audio data from one sample format to another.
av_dlog(ac->avr,"%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)
signed 16 bits
Definition: samplefmt.h:52
void ff_audio_convert_init_x86(AudioConvert *ac)
int channel_zero[AVRESAMPLE_MAX_CHANNELS]
dest index to zero
#define FFALIGN(x, a)
Definition: common.h:63
int nb_samples
current number of samples
Definition: audio_data.h:41
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
conv_func_interleave * conv_interleave
Definition: audio_convert.c:64
uint8_t
AV_SAMPLE_FMT_U8
#define llrintf(x)
Definition: libm.h:117
#define lrintf(x)
Definition: libm_mips.h:70
end end ac
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.
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=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);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_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_dlog(ac->avr,"%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
#define U(x)
enum AVResampleDitherMethod dither_method
dither method
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int stride
sample byte offset within a plane
Definition: audio_data.h:48
#define ARCH_X86
Definition: config.h:35
int channels
channel count
Definition: oss_audio.c:50
Spectrum Plot time data
av_cold void ff_audio_convert_init_arm(AudioConvert *ac)
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
void ff_audio_convert_free(AudioConvert **ac)
Free AudioConvert.
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.
int is_planar
sample format is planar
Definition: audio_data.h:45
int channel_copy[AVRESAMPLE_MAX_CHANNELS]
dest index to copy from
signed 32 bits
Definition: samplefmt.h:53
#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:58
int do_remap
remap needed
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:249
int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src)
Convert audio sample format with dithering.
#define ARCH_ARM
Definition: config.h:16
int32_t
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition: samplefmt.c:73
static int convert(uint8_t x)
Definition: xbmdec.c:35
#define CONV_FUNC_GROUP(ofmt, otype, ifmt, itype, expr)
conv_func_interleave * conv_interleave_generic
Definition: audio_convert.c:65
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:47
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:104
NULL
Definition: eval.c:55
sample_rate
const char * func_descr
Definition: audio_convert.c:59
typedef void(RENAME(mix_any_func_type))
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:37
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:103
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
#define llrint(x)
Definition: libm.h:112
Replacements for frequently missing libm functions.
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt)
Check if the sample format is planar.
Definition: samplefmt.c:118
static av_always_inline av_const long int lrint(double x)
Definition: libm.h:148
conv_func_flat * conv_flat_generic
Definition: audio_convert.c:63
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
int channel_map[AVRESAMPLE_MAX_CHANNELS]
source index of each output channel, -1 if not remapped
ConvFuncType
Definition: audio_convert.c:34
int samples_align
allocated samples alignment
Definition: audio_data.h:52
const char * func_descr_generic
Definition: audio_convert.c:60
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
common internal and external API header
int do_copy
copy needed
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
int len
enum ConvFuncType func_type
Definition: audio_convert.c:61
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
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=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);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_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_dlog(ac->avr,"%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 ptr_align
minimum data pointer alignment
Definition: audio_data.h:51