2 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3 * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
5 * This file is part of FFmpeg.
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.
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.
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
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"
36 CONV_FUNC_TYPE_INTERLEAVE
,
37 CONV_FUNC_TYPE_DEINTERLEAVE
,
40 typedef void (conv_func_flat
)(uint8_t *out
, const uint8_t *in
, int len
);
42 typedef void (conv_func_interleave
)(uint8_t *out
, uint8_t *const *in
,
43 int len
, int channels
);
45 typedef void (conv_func_deinterleave
)(uint8_t **out
, const uint8_t *in
, int len
,
49 AVAudioResampleContext
*avr
;
51 enum AVSampleFormat in_fmt
;
52 enum AVSampleFormat out_fmt
;
58 int has_optimized_func
;
59 const char *func_descr
;
60 const char *func_descr_generic
;
61 enum ConvFuncType func_type
;
62 conv_func_flat
*conv_flat
;
63 conv_func_flat
*conv_flat_generic
;
64 conv_func_interleave
*conv_interleave
;
65 conv_func_interleave
*conv_interleave_generic
;
66 conv_func_deinterleave
*conv_deinterleave
;
67 conv_func_deinterleave
*conv_deinterleave_generic
;
70 void ff_audio_convert_set_func(AudioConvert
*ac
, enum AVSampleFormat out_fmt
,
71 enum AVSampleFormat in_fmt
, int channels
,
72 int ptr_align
, int samples_align
,
73 const char *descr
, void *conv
)
77 switch (ac
->func_type
) {
78 case CONV_FUNC_TYPE_FLAT
:
79 if (av_get_packed_sample_fmt(ac
->in_fmt
) == in_fmt
&&
80 av_get_packed_sample_fmt(ac
->out_fmt
) == out_fmt
) {
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
;
89 ac
->has_optimized_func
= 1;
94 case CONV_FUNC_TYPE_INTERLEAVE
:
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) {
102 ac
->conv_interleave_generic
= conv
;
103 ac
->func_descr_generic
= descr
;
105 ac
->has_optimized_func
= 1;
110 case CONV_FUNC_TYPE_DEINTERLEAVE
:
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) {
118 ac
->conv_deinterleave_generic
= conv
;
119 ac
->func_descr_generic
= descr
;
121 ac
->has_optimized_func
= 1;
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
);
134 #define CONV_FUNC_NAME(dst_fmt, src_fmt) conv_ ## src_fmt ## _to_ ## dst_fmt
136 #define CONV_LOOP(otype, expr) \
138 *(otype *)po = expr; \
141 } while (po < end); \
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, \
147 int is = sizeof(itype); \
148 int os = sizeof(otype); \
149 const uint8_t *pi = in; \
151 uint8_t *end = out + os * len; \
152 CONV_LOOP(otype, expr) \
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) \
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) \
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) \
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) \
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)
192 CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8
, uint8_t, AV_SAMPLE_FMT_U8
, uint8_t, *(const uint8_t *)pi
)
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
)
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));
223 static void set_generic_function(AudioConvert
*ac
)
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
)
252 void ff_audio_convert_free(AudioConvert
**ac
)
256 ff_dither_free(&(*ac
)->dc
);
260 AudioConvert
*ff_audio_convert_alloc(AVAudioResampleContext
*avr
,
261 enum AVSampleFormat out_fmt
,
262 enum AVSampleFormat in_fmt
,
263 int channels
, int sample_rate
,
267 int in_planar
, out_planar
;
269 ac
= av_mallocz(sizeof(*ac
));
274 ac
->out_fmt
= out_fmt
;
276 ac
->channels
= channels
;
277 ac
->apply_map
= apply_map
;
279 if (avr
->dither_method
!= AV_RESAMPLE_DITHER_NONE
&&
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
,
291 in_planar
= ff_sample_fmt_is_planar(in_fmt
, channels
);
292 out_planar
= ff_sample_fmt_is_planar(out_fmt
, channels
);
294 if (in_planar
== out_planar
) {
295 ac
->func_type
= CONV_FUNC_TYPE_FLAT
;
296 ac
->planes
= in_planar
? ac
->channels
: 1;
297 } else if (in_planar
)
298 ac
->func_type
= CONV_FUNC_TYPE_INTERLEAVE
;
300 ac
->func_type
= CONV_FUNC_TYPE_DEINTERLEAVE
;
302 set_generic_function(ac
);
305 ff_audio_convert_init_aarch64(ac
);
307 ff_audio_convert_init_arm(ac
);
309 ff_audio_convert_init_x86(ac
);
314 int ff_audio_convert(AudioConvert
*ac
, AudioData
*out
, AudioData
*in
)
317 int len
= in
->nb_samples
;
321 /* dithered conversion */
322 av_dlog(ac
->avr
, "%d samples - audio_convert: %s to %s (dithered)\n",
323 len
, av_get_sample_fmt_name(ac
->in_fmt
),
324 av_get_sample_fmt_name(ac
->out_fmt
));
326 return ff_convert_dither(ac
->dc
, out
, in
);
329 /* determine whether to use the optimized function based on pointer and
330 samples alignment in both the input and output */
331 if (ac
->has_optimized_func
) {
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
) {
340 av_dlog(ac
->avr
, "%d samples - audio_convert: %s to %s (%s)\n", len
,
341 av_get_sample_fmt_name(ac
->in_fmt
),
342 av_get_sample_fmt_name(ac
->out_fmt
),
343 use_generic
? ac
->func_descr_generic
: ac
->func_descr
);
346 ChannelMapInfo
*map
= &ac
->avr
->ch_map_info
;
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
);
354 if (ff_sample_fmt_is_planar(ac
->in_fmt
, ac
->channels
)) {
355 conv_func_flat
*convert
= use_generic
? ac
->conv_flat_generic
:
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
);
362 uint8_t *data
[AVRESAMPLE_MAX_CHANNELS
];
363 conv_func_deinterleave
*convert
= use_generic
?
364 ac
->conv_deinterleave_generic
:
365 ac
->conv_deinterleave
;
367 for (p
= 0; p
< ac
->channels
; p
++)
368 data
[map
->input_map
[p
]] = out
->data
[p
];
370 convert(data
, in
->data
[0], len
, ac
->channels
);
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
]],
378 else if (map
->channel_zero
[p
])
379 av_samples_set_silence(&out
->data
[p
], 0, len
, 1, ac
->out_fmt
);
383 switch (ac
->func_type
) {
384 case CONV_FUNC_TYPE_FLAT
: {
388 for (p
= 0; p
< ac
->planes
; p
++)
389 ac
->conv_flat_generic(out
->data
[p
], in
->data
[p
], len
);
391 for (p
= 0; p
< ac
->planes
; p
++)
392 ac
->conv_flat(out
->data
[p
], in
->data
[p
], len
);
396 case CONV_FUNC_TYPE_INTERLEAVE
:
398 ac
->conv_interleave_generic(out
->data
[0], in
->data
, len
,
401 ac
->conv_interleave(out
->data
[0], in
->data
, len
, ac
->channels
);
403 case CONV_FUNC_TYPE_DEINTERLEAVE
:
405 ac
->conv_deinterleave_generic(out
->data
, in
->data
[0], len
,
408 ac
->conv_deinterleave(out
->data
, in
->data
[0], len
,
414 out
->nb_samples
= in
->nb_samples
;