annotate ffmpeg/libavresample/audio_convert.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
yading@11 3 * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
yading@11 4 *
yading@11 5 * This file is part of Libav.
yading@11 6 *
yading@11 7 * Libav is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * Libav is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with Libav; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 #include <stdint.h>
yading@11 23
yading@11 24 #include "config.h"
yading@11 25 #include "libavutil/common.h"
yading@11 26 #include "libavutil/libm.h"
yading@11 27 #include "libavutil/log.h"
yading@11 28 #include "libavutil/mem.h"
yading@11 29 #include "libavutil/samplefmt.h"
yading@11 30 #include "audio_convert.h"
yading@11 31 #include "audio_data.h"
yading@11 32 #include "dither.h"
yading@11 33
yading@11 34 enum ConvFuncType {
yading@11 35 CONV_FUNC_TYPE_FLAT,
yading@11 36 CONV_FUNC_TYPE_INTERLEAVE,
yading@11 37 CONV_FUNC_TYPE_DEINTERLEAVE,
yading@11 38 };
yading@11 39
yading@11 40 typedef void (conv_func_flat)(uint8_t *out, const uint8_t *in, int len);
yading@11 41
yading@11 42 typedef void (conv_func_interleave)(uint8_t *out, uint8_t *const *in,
yading@11 43 int len, int channels);
yading@11 44
yading@11 45 typedef void (conv_func_deinterleave)(uint8_t **out, const uint8_t *in, int len,
yading@11 46 int channels);
yading@11 47
yading@11 48 struct AudioConvert {
yading@11 49 AVAudioResampleContext *avr;
yading@11 50 DitherContext *dc;
yading@11 51 enum AVSampleFormat in_fmt;
yading@11 52 enum AVSampleFormat out_fmt;
yading@11 53 int apply_map;
yading@11 54 int channels;
yading@11 55 int planes;
yading@11 56 int ptr_align;
yading@11 57 int samples_align;
yading@11 58 int has_optimized_func;
yading@11 59 const char *func_descr;
yading@11 60 const char *func_descr_generic;
yading@11 61 enum ConvFuncType func_type;
yading@11 62 conv_func_flat *conv_flat;
yading@11 63 conv_func_flat *conv_flat_generic;
yading@11 64 conv_func_interleave *conv_interleave;
yading@11 65 conv_func_interleave *conv_interleave_generic;
yading@11 66 conv_func_deinterleave *conv_deinterleave;
yading@11 67 conv_func_deinterleave *conv_deinterleave_generic;
yading@11 68 };
yading@11 69
yading@11 70 void ff_audio_convert_set_func(AudioConvert *ac, enum AVSampleFormat out_fmt,
yading@11 71 enum AVSampleFormat in_fmt, int channels,
yading@11 72 int ptr_align, int samples_align,
yading@11 73 const char *descr, void *conv)
yading@11 74 {
yading@11 75 int found = 0;
yading@11 76
yading@11 77 switch (ac->func_type) {
yading@11 78 case CONV_FUNC_TYPE_FLAT:
yading@11 79 if (av_get_packed_sample_fmt(ac->in_fmt) == in_fmt &&
yading@11 80 av_get_packed_sample_fmt(ac->out_fmt) == out_fmt) {
yading@11 81 ac->conv_flat = conv;
yading@11 82 ac->func_descr = descr;
yading@11 83 ac->ptr_align = ptr_align;
yading@11 84 ac->samples_align = samples_align;
yading@11 85 if (ptr_align == 1 && samples_align == 1) {
yading@11 86 ac->conv_flat_generic = conv;
yading@11 87 ac->func_descr_generic = descr;
yading@11 88 } else {
yading@11 89 ac->has_optimized_func = 1;
yading@11 90 }
yading@11 91 found = 1;
yading@11 92 }
yading@11 93 break;
yading@11 94 case CONV_FUNC_TYPE_INTERLEAVE:
yading@11 95 if (ac->in_fmt == in_fmt && ac->out_fmt == out_fmt &&
yading@11 96 (!channels || ac->channels == channels)) {
yading@11 97 ac->conv_interleave = conv;
yading@11 98 ac->func_descr = descr;
yading@11 99 ac->ptr_align = ptr_align;
yading@11 100 ac->samples_align = samples_align;
yading@11 101 if (ptr_align == 1 && samples_align == 1) {
yading@11 102 ac->conv_interleave_generic = conv;
yading@11 103 ac->func_descr_generic = descr;
yading@11 104 } else {
yading@11 105 ac->has_optimized_func = 1;
yading@11 106 }
yading@11 107 found = 1;
yading@11 108 }
yading@11 109 break;
yading@11 110 case CONV_FUNC_TYPE_DEINTERLEAVE:
yading@11 111 if (ac->in_fmt == in_fmt && ac->out_fmt == out_fmt &&
yading@11 112 (!channels || ac->channels == channels)) {
yading@11 113 ac->conv_deinterleave = conv;
yading@11 114 ac->func_descr = descr;
yading@11 115 ac->ptr_align = ptr_align;
yading@11 116 ac->samples_align = samples_align;
yading@11 117 if (ptr_align == 1 && samples_align == 1) {
yading@11 118 ac->conv_deinterleave_generic = conv;
yading@11 119 ac->func_descr_generic = descr;
yading@11 120 } else {
yading@11 121 ac->has_optimized_func = 1;
yading@11 122 }
yading@11 123 found = 1;
yading@11 124 }
yading@11 125 break;
yading@11 126 }
yading@11 127 if (found) {
yading@11 128 av_log(ac->avr, AV_LOG_DEBUG, "audio_convert: found function: %-4s "
yading@11 129 "to %-4s (%s)\n", av_get_sample_fmt_name(ac->in_fmt),
yading@11 130 av_get_sample_fmt_name(ac->out_fmt), descr);
yading@11 131 }
yading@11 132 }
yading@11 133
yading@11 134 #define CONV_FUNC_NAME(dst_fmt, src_fmt) conv_ ## src_fmt ## _to_ ## dst_fmt
yading@11 135
yading@11 136 #define CONV_LOOP(otype, expr) \
yading@11 137 do { \
yading@11 138 *(otype *)po = expr; \
yading@11 139 pi += is; \
yading@11 140 po += os; \
yading@11 141 } while (po < end); \
yading@11 142
yading@11 143 #define CONV_FUNC_FLAT(ofmt, otype, ifmt, itype, expr) \
yading@11 144 static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *out, const uint8_t *in, \
yading@11 145 int len) \
yading@11 146 { \
yading@11 147 int is = sizeof(itype); \
yading@11 148 int os = sizeof(otype); \
yading@11 149 const uint8_t *pi = in; \
yading@11 150 uint8_t *po = out; \
yading@11 151 uint8_t *end = out + os * len; \
yading@11 152 CONV_LOOP(otype, expr) \
yading@11 153 }
yading@11 154
yading@11 155 #define CONV_FUNC_INTERLEAVE(ofmt, otype, ifmt, itype, expr) \
yading@11 156 static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *out, const uint8_t **in, \
yading@11 157 int len, int channels) \
yading@11 158 { \
yading@11 159 int ch; \
yading@11 160 int out_bps = sizeof(otype); \
yading@11 161 int is = sizeof(itype); \
yading@11 162 int os = channels * out_bps; \
yading@11 163 for (ch = 0; ch < channels; ch++) { \
yading@11 164 const uint8_t *pi = in[ch]; \
yading@11 165 uint8_t *po = out + ch * out_bps; \
yading@11 166 uint8_t *end = po + os * len; \
yading@11 167 CONV_LOOP(otype, expr) \
yading@11 168 } \
yading@11 169 }
yading@11 170
yading@11 171 #define CONV_FUNC_DEINTERLEAVE(ofmt, otype, ifmt, itype, expr) \
yading@11 172 static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t **out, const uint8_t *in, \
yading@11 173 int len, int channels) \
yading@11 174 { \
yading@11 175 int ch; \
yading@11 176 int in_bps = sizeof(itype); \
yading@11 177 int is = channels * in_bps; \
yading@11 178 int os = sizeof(otype); \
yading@11 179 for (ch = 0; ch < channels; ch++) { \
yading@11 180 const uint8_t *pi = in + ch * in_bps; \
yading@11 181 uint8_t *po = out[ch]; \
yading@11 182 uint8_t *end = po + os * len; \
yading@11 183 CONV_LOOP(otype, expr) \
yading@11 184 } \
yading@11 185 }
yading@11 186
yading@11 187 #define CONV_FUNC_GROUP(ofmt, otype, ifmt, itype, expr) \
yading@11 188 CONV_FUNC_FLAT( ofmt, otype, ifmt, itype, expr) \
yading@11 189 CONV_FUNC_INTERLEAVE( ofmt, otype, ifmt ## P, itype, expr) \
yading@11 190 CONV_FUNC_DEINTERLEAVE(ofmt ## P, otype, ifmt, itype, expr)
yading@11 191
yading@11 192 CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_U8, uint8_t, *(const uint8_t *)pi)
yading@11 193 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) << 8)
yading@11 194 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) << 24)
yading@11 195 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) * (1.0f / (1 << 7)))
yading@11 196 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t, (*(const uint8_t *)pi - 0x80) * (1.0 / (1 << 7)))
yading@11 197 CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t, (*(const int16_t *)pi >> 8) + 0x80)
yading@11 198 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi)
yading@11 199 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi << 16)
yading@11 200 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi * (1.0f / (1 << 15)))
yading@11 201 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *)pi * (1.0 / (1 << 15)))
yading@11 202 CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t, (*(const int32_t *)pi >> 24) + 0x80)
yading@11 203 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi >> 16)
yading@11 204 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi)
yading@11 205 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi * (1.0f / (1U << 31)))
yading@11 206 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *)pi * (1.0 / (1U << 31)))
yading@11 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))
yading@11 208 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16( lrintf(*(const float *)pi * (1 << 15))))
yading@11 209 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *)pi * (1U << 31))))
yading@11 210 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_FLT, float, *(const float *)pi)
yading@11 211 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_FLT, float, *(const float *)pi)
yading@11 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))
yading@11 213 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16( lrint(*(const double *)pi * (1 << 15))))
yading@11 214 CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *)pi * (1U << 31))))
yading@11 215 CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_DBL, double, *(const double *)pi)
yading@11 216 CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_DBL, double, *(const double *)pi)
yading@11 217
yading@11 218 #define SET_CONV_FUNC_GROUP(ofmt, ifmt) \
yading@11 219 ff_audio_convert_set_func(ac, ofmt, ifmt, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt, ifmt)); \
yading@11 220 ff_audio_convert_set_func(ac, ofmt ## P, ifmt, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt ## P, ifmt)); \
yading@11 221 ff_audio_convert_set_func(ac, ofmt, ifmt ## P, 0, 1, 1, "C", CONV_FUNC_NAME(ofmt, ifmt ## P));
yading@11 222
yading@11 223 static void set_generic_function(AudioConvert *ac)
yading@11 224 {
yading@11 225 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8)
yading@11 226 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8)
yading@11 227 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8)
yading@11 228 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8)
yading@11 229 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8)
yading@11 230 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16)
yading@11 231 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16)
yading@11 232 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16)
yading@11 233 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16)
yading@11 234 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16)
yading@11 235 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32)
yading@11 236 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32)
yading@11 237 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32)
yading@11 238 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32)
yading@11 239 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32)
yading@11 240 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT)
yading@11 241 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT)
yading@11 242 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT)
yading@11 243 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT)
yading@11 244 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT)
yading@11 245 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL)
yading@11 246 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL)
yading@11 247 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL)
yading@11 248 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL)
yading@11 249 SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL)
yading@11 250 }
yading@11 251
yading@11 252 void ff_audio_convert_free(AudioConvert **ac)
yading@11 253 {
yading@11 254 if (!*ac)
yading@11 255 return;
yading@11 256 ff_dither_free(&(*ac)->dc);
yading@11 257 av_freep(ac);
yading@11 258 }
yading@11 259
yading@11 260 AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
yading@11 261 enum AVSampleFormat out_fmt,
yading@11 262 enum AVSampleFormat in_fmt,
yading@11 263 int channels, int sample_rate,
yading@11 264 int apply_map)
yading@11 265 {
yading@11 266 AudioConvert *ac;
yading@11 267 int in_planar, out_planar;
yading@11 268
yading@11 269 ac = av_mallocz(sizeof(*ac));
yading@11 270 if (!ac)
yading@11 271 return NULL;
yading@11 272
yading@11 273 ac->avr = avr;
yading@11 274 ac->out_fmt = out_fmt;
yading@11 275 ac->in_fmt = in_fmt;
yading@11 276 ac->channels = channels;
yading@11 277 ac->apply_map = apply_map;
yading@11 278
yading@11 279 if (avr->dither_method != AV_RESAMPLE_DITHER_NONE &&
yading@11 280 av_get_packed_sample_fmt(out_fmt) == AV_SAMPLE_FMT_S16 &&
yading@11 281 av_get_bytes_per_sample(in_fmt) > 2) {
yading@11 282 ac->dc = ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate,
yading@11 283 apply_map);
yading@11 284 if (!ac->dc) {
yading@11 285 av_free(ac);
yading@11 286 return NULL;
yading@11 287 }
yading@11 288 return ac;
yading@11 289 }
yading@11 290
yading@11 291 in_planar = av_sample_fmt_is_planar(in_fmt);
yading@11 292 out_planar = av_sample_fmt_is_planar(out_fmt);
yading@11 293
yading@11 294 if (in_planar == out_planar) {
yading@11 295 ac->func_type = CONV_FUNC_TYPE_FLAT;
yading@11 296 ac->planes = in_planar ? ac->channels : 1;
yading@11 297 } else if (in_planar)
yading@11 298 ac->func_type = CONV_FUNC_TYPE_INTERLEAVE;
yading@11 299 else
yading@11 300 ac->func_type = CONV_FUNC_TYPE_DEINTERLEAVE;
yading@11 301
yading@11 302 set_generic_function(ac);
yading@11 303
yading@11 304 if (ARCH_ARM)
yading@11 305 ff_audio_convert_init_arm(ac);
yading@11 306 if (ARCH_X86)
yading@11 307 ff_audio_convert_init_x86(ac);
yading@11 308
yading@11 309 return ac;
yading@11 310 }
yading@11 311
yading@11 312 int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
yading@11 313 {
yading@11 314 int use_generic = 1;
yading@11 315 int len = in->nb_samples;
yading@11 316 int p;
yading@11 317
yading@11 318 if (ac->dc) {
yading@11 319 /* dithered conversion */
yading@11 320 av_dlog(ac->avr, "%d samples - audio_convert: %s to %s (dithered)\n",
yading@11 321 len, av_get_sample_fmt_name(ac->in_fmt),
yading@11 322 av_get_sample_fmt_name(ac->out_fmt));
yading@11 323
yading@11 324 return ff_convert_dither(ac->dc, out, in);
yading@11 325 }
yading@11 326
yading@11 327 /* determine whether to use the optimized function based on pointer and
yading@11 328 samples alignment in both the input and output */
yading@11 329 if (ac->has_optimized_func) {
yading@11 330 int ptr_align = FFMIN(in->ptr_align, out->ptr_align);
yading@11 331 int samples_align = FFMIN(in->samples_align, out->samples_align);
yading@11 332 int aligned_len = FFALIGN(len, ac->samples_align);
yading@11 333 if (!(ptr_align % ac->ptr_align) && samples_align >= aligned_len) {
yading@11 334 len = aligned_len;
yading@11 335 use_generic = 0;
yading@11 336 }
yading@11 337 }
yading@11 338 av_dlog(ac->avr, "%d samples - audio_convert: %s to %s (%s)\n", len,
yading@11 339 av_get_sample_fmt_name(ac->in_fmt),
yading@11 340 av_get_sample_fmt_name(ac->out_fmt),
yading@11 341 use_generic ? ac->func_descr_generic : ac->func_descr);
yading@11 342
yading@11 343 if (ac->apply_map) {
yading@11 344 ChannelMapInfo *map = &ac->avr->ch_map_info;
yading@11 345
yading@11 346 if (!av_sample_fmt_is_planar(ac->out_fmt)) {
yading@11 347 av_log(ac->avr, AV_LOG_ERROR, "cannot remap packed format during conversion\n");
yading@11 348 return AVERROR(EINVAL);
yading@11 349 }
yading@11 350
yading@11 351 if (map->do_remap) {
yading@11 352 if (av_sample_fmt_is_planar(ac->in_fmt)) {
yading@11 353 conv_func_flat *convert = use_generic ? ac->conv_flat_generic :
yading@11 354 ac->conv_flat;
yading@11 355
yading@11 356 for (p = 0; p < ac->planes; p++)
yading@11 357 if (map->channel_map[p] >= 0)
yading@11 358 convert(out->data[p], in->data[map->channel_map[p]], len);
yading@11 359 } else {
yading@11 360 uint8_t *data[AVRESAMPLE_MAX_CHANNELS];
yading@11 361 conv_func_deinterleave *convert = use_generic ?
yading@11 362 ac->conv_deinterleave_generic :
yading@11 363 ac->conv_deinterleave;
yading@11 364
yading@11 365 for (p = 0; p < ac->channels; p++)
yading@11 366 data[map->input_map[p]] = out->data[p];
yading@11 367
yading@11 368 convert(data, in->data[0], len, ac->channels);
yading@11 369 }
yading@11 370 }
yading@11 371 if (map->do_copy || map->do_zero) {
yading@11 372 for (p = 0; p < ac->planes; p++) {
yading@11 373 if (map->channel_copy[p])
yading@11 374 memcpy(out->data[p], out->data[map->channel_copy[p]],
yading@11 375 len * out->stride);
yading@11 376 else if (map->channel_zero[p])
yading@11 377 av_samples_set_silence(&out->data[p], 0, len, 1, ac->out_fmt);
yading@11 378 }
yading@11 379 }
yading@11 380 } else {
yading@11 381 switch (ac->func_type) {
yading@11 382 case CONV_FUNC_TYPE_FLAT: {
yading@11 383 if (!in->is_planar)
yading@11 384 len *= in->channels;
yading@11 385 if (use_generic) {
yading@11 386 for (p = 0; p < ac->planes; p++)
yading@11 387 ac->conv_flat_generic(out->data[p], in->data[p], len);
yading@11 388 } else {
yading@11 389 for (p = 0; p < ac->planes; p++)
yading@11 390 ac->conv_flat(out->data[p], in->data[p], len);
yading@11 391 }
yading@11 392 break;
yading@11 393 }
yading@11 394 case CONV_FUNC_TYPE_INTERLEAVE:
yading@11 395 if (use_generic)
yading@11 396 ac->conv_interleave_generic(out->data[0], in->data, len,
yading@11 397 ac->channels);
yading@11 398 else
yading@11 399 ac->conv_interleave(out->data[0], in->data, len, ac->channels);
yading@11 400 break;
yading@11 401 case CONV_FUNC_TYPE_DEINTERLEAVE:
yading@11 402 if (use_generic)
yading@11 403 ac->conv_deinterleave_generic(out->data, in->data[0], len,
yading@11 404 ac->channels);
yading@11 405 else
yading@11 406 ac->conv_deinterleave(out->data, in->data[0], len,
yading@11 407 ac->channels);
yading@11 408 break;
yading@11 409 }
yading@11 410 }
yading@11 411
yading@11 412 out->nb_samples = in->nb_samples;
yading@11 413 return 0;
yading@11 414 }