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 
42 typedef void (conv_func_interleave)(uint8_t *out, uint8_t *const *in,
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;
84  ac->samples_align = samples_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;
100  ac->samples_align = samples_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;
116  ac->samples_align = samples_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)
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)))
203 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi >> 16)
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 {
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 
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",
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);
333  int samples_align = FFMIN(in->samples_align, out->samples_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 {
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 }
ff_audio_convert_free
void ff_audio_convert_free(AudioConvert **ac)
Free AudioConvert.
ff_sample_fmt_is_planar
int ff_sample_fmt_is_planar(enum AVSampleFormat sample_fmt, int channels)
Definition: audio_data.c:51
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
CONV_FUNC_TYPE_INTERLEAVE
@ CONV_FUNC_TYPE_INTERLEAVE
Definition: audio_convert.c:36
AudioConvert::conv_deinterleave
conv_func_deinterleave * conv_deinterleave
Definition: audio_convert.c:66
libm.h
DitherContext
Definition: dither.c:54
audio_convert.h
AVRESAMPLE_MAX_CHANNELS
#define AVRESAMPLE_MAX_CHANNELS
Definition: avresample.h:104
AudioConvert::conv_interleave_generic
conv_func_interleave * conv_interleave_generic
Definition: audio_convert.c:65
AudioConvert::out_fmt
enum AVSampleFormat out_fmt
Definition: audio_convert.c:52
AudioConvert::channels
int channels
Definition: audio_convert.c:54
data
const char data[16]
Definition: mxf.c:142
convert
Definition: convert.py:1
ff_audio_convert_init_arm
av_cold void ff_audio_convert_init_arm(AudioConvert *ac)
Definition: audio_convert_init.c:34
sample_rate
sample_rate
Definition: ffmpeg_filter.c:158
AudioConvert::func_descr
const char * func_descr
Definition: audio_convert.c:59
convert
static void convert(float y, float u, float v, float *b, float *g, float *r)
Definition: exr.c:967
SET_CONV_FUNC_GROUP
#define SET_CONV_FUNC_GROUP(ofmt, ifmt)
AudioData
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
CONV_FUNC_TYPE_DEINTERLEAVE
@ CONV_FUNC_TYPE_DEINTERLEAVE
Definition: audio_convert.c:37
AVAudioResampleContext
Definition: internal.h:53
ChannelMapInfo
Definition: internal.h:43
U
#define U(x)
Definition: vp56_arith.h:37
AVAudioResampleContext::ch_map_info
ChannelMapInfo ch_map_info
Definition: internal.h:107
samplefmt.h
AudioConvert::in_fmt
enum AVSampleFormat in_fmt
Definition: audio_convert.c:51
lrint
#define lrint
Definition: tablegen.h:53
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:220
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
AudioConvert::planes
int planes
Definition: audio_convert.c:55
llrintf
#define llrintf(x)
Definition: libm.h:399
dither.h
AudioConvert::avr
AVAudioResampleContext * avr
Definition: audio_convert.c:49
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
channels
channels
Definition: aptx.h:33
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
f
#define f(width, name)
Definition: cbs_vp9.c:255
conv
static int conv(int samples, float **pcm, char *buf, int channels)
Definition: libvorbisdec.c:131
int32_t
int32_t
Definition: audio_convert.c:194
conv_func_deinterleave
void() conv_func_deinterleave(uint8_t **out, const uint8_t *in, int len, int channels)
Definition: audio_convert.c:45
av_clip_int16
#define av_clip_int16
Definition: common.h:137
NULL
#define NULL
Definition: coverity.c:32
AV_SAMPLE_FMT_U8
AV_SAMPLE_FMT_U8
Definition: audio_convert.c:194
audio_data.h
AudioConvert::conv_flat_generic
conv_func_flat * conv_flat_generic
Definition: audio_convert.c:63
ff_audio_convert_init_x86
void ff_audio_convert_init_x86(AudioConvert *ac)
Definition: audio_convert_init.c:146
av_clipl_int32
#define av_clipl_int32
Definition: common.h:140
av_log
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)
ff_dither_alloc
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
AV_RESAMPLE_DITHER_NONE
AV_RESAMPLE_DITHER_NONE
Do not use dithering.
Definition: avresample.h:133
AudioConvert::func_descr_generic
const char * func_descr_generic
Definition: audio_convert.c:60
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
AudioConvert::dc
DitherContext * dc
Definition: audio_convert.c:50
AudioConvert::conv_interleave
conv_func_interleave * conv_interleave
Definition: audio_convert.c:64
ff_convert_dither
int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src)
Convert audio sample format with dithering.
Definition: dither.c:242
conv_func_interleave
void() conv_func_interleave(uint8_t *out, uint8_t *const *in, int len, int channels)
Definition: audio_convert.c:42
AVAudioResampleContext::dither_method
enum AVResampleDitherMethod dither_method
dither method
Definition: internal.h:75
in
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
Definition: audio_convert.c:326
log.h
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
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
AudioConvert::conv_deinterleave_generic
conv_func_deinterleave * conv_deinterleave_generic
Definition: audio_convert.c:67
common.h
ff_audio_convert_init_aarch64
av_cold void ff_audio_convert_init_aarch64(AudioConvert *ac)
Definition: audio_convert_init.c:34
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AudioConvert::ptr_align
int ptr_align
Definition: audio_convert.c:56
uint8_t
uint8_t
Definition: audio_convert.c:194
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:61
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
len
int len
Definition: vorbis_enc_data.h:452
ConvFuncType
ConvFuncType
Definition: audio_convert.c:34
av_samples_set_silence
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
out
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
Definition: audio_convert.c:326
conv_func_flat
void() conv_func_flat(uint8_t *out, const uint8_t *in, int len)
Definition: audio_convert.c:40
ff_audio_convert_set_func
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
AudioConvert
Definition: audio_convert.c:48
av_get_packed_sample_fmt
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
av_clip_uint8
#define av_clip_uint8
Definition: common.h:128
ff_audio_convert_alloc
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.
AudioConvert::conv_flat
conv_func_flat * conv_flat
Definition: audio_convert.c:62
mem.h
llrint
#define llrint(x)
Definition: libm.h:394
AudioConvert::func_type
enum ConvFuncType func_type
Definition: audio_convert.c:61
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
ff_dither_free
void ff_dither_free(DitherContext **cp)
Free a DitherContext.
Definition: dither.c:312
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AudioConvert::has_optimized_func
int has_optimized_func
Definition: audio_convert.c:58
CONV_FUNC_GROUP
#define CONV_FUNC_GROUP(ofmt, otype, ifmt, itype, expr)
Definition: audio_convert.c:187
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:64
AudioConvert::samples_align
int samples_align
Definition: audio_convert.c:57
CONV_FUNC_TYPE_FLAT
@ CONV_FUNC_TYPE_FLAT
Definition: audio_convert.c:35
AV_SAMPLE_FMT_S32
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition: samplefmt.h:62
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63
ff_audio_convert
int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
Convert audio data from one sample format to another.
AudioConvert::apply_map
int apply_map
Definition: audio_convert.c:53