LCOV - code coverage report
Current view: top level - libavresample - audio_convert.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 189 0.0 %
Date: 2017-10-22 09:09:27 Functions: 0 80 0.0 %

          Line data    Source code
       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             : 
      34             : enum ConvFuncType {
      35             :     CONV_FUNC_TYPE_FLAT,
      36             :     CONV_FUNC_TYPE_INTERLEAVE,
      37             :     CONV_FUNC_TYPE_DEINTERLEAVE,
      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 {
      49             :     AVAudioResampleContext *avr;
      50             :     DitherContext *dc;
      51             :     enum AVSampleFormat in_fmt;
      52             :     enum AVSampleFormat out_fmt;
      53             :     int apply_map;
      54             :     int channels;
      55             :     int planes;
      56             :     int ptr_align;
      57             :     int samples_align;
      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;
      68             : };
      69             : 
      70           0 : 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)
      74             : {
      75           0 :     int found = 0;
      76             : 
      77           0 :     switch (ac->func_type) {
      78           0 :     case CONV_FUNC_TYPE_FLAT:
      79           0 :         if (av_get_packed_sample_fmt(ac->in_fmt)  == in_fmt &&
      80           0 :             av_get_packed_sample_fmt(ac->out_fmt) == out_fmt) {
      81           0 :             ac->conv_flat     = conv;
      82           0 :             ac->func_descr    = descr;
      83           0 :             ac->ptr_align     = ptr_align;
      84           0 :             ac->samples_align = samples_align;
      85           0 :             if (ptr_align == 1 && samples_align == 1) {
      86           0 :                 ac->conv_flat_generic  = conv;
      87           0 :                 ac->func_descr_generic = descr;
      88             :             } else {
      89           0 :                 ac->has_optimized_func = 1;
      90             :             }
      91           0 :             found = 1;
      92             :         }
      93           0 :         break;
      94           0 :     case CONV_FUNC_TYPE_INTERLEAVE:
      95           0 :         if (ac->in_fmt == in_fmt && ac->out_fmt == out_fmt &&
      96           0 :             (!channels || ac->channels == channels)) {
      97           0 :             ac->conv_interleave = conv;
      98           0 :             ac->func_descr      = descr;
      99           0 :             ac->ptr_align       = ptr_align;
     100           0 :             ac->samples_align   = samples_align;
     101           0 :             if (ptr_align == 1 && samples_align == 1) {
     102           0 :                 ac->conv_interleave_generic = conv;
     103           0 :                 ac->func_descr_generic      = descr;
     104             :             } else {
     105           0 :                 ac->has_optimized_func = 1;
     106             :             }
     107           0 :             found = 1;
     108             :         }
     109           0 :         break;
     110           0 :     case CONV_FUNC_TYPE_DEINTERLEAVE:
     111           0 :         if (ac->in_fmt == in_fmt && ac->out_fmt == out_fmt &&
     112           0 :             (!channels || ac->channels == channels)) {
     113           0 :             ac->conv_deinterleave = conv;
     114           0 :             ac->func_descr        = descr;
     115           0 :             ac->ptr_align         = ptr_align;
     116           0 :             ac->samples_align     = samples_align;
     117           0 :             if (ptr_align == 1 && samples_align == 1) {
     118           0 :                 ac->conv_deinterleave_generic = conv;
     119           0 :                 ac->func_descr_generic        = descr;
     120             :             } else {
     121           0 :                 ac->has_optimized_func = 1;
     122             :             }
     123           0 :             found = 1;
     124             :         }
     125           0 :         break;
     126             :     }
     127           0 :     if (found) {
     128           0 :         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           0 : }
     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             : 
     192           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8,  uint8_t, AV_SAMPLE_FMT_U8,  uint8_t,  *(const uint8_t *)pi)
     193           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8,  uint8_t, (*(const uint8_t *)pi - 0x80) <<  8)
     194           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8,  uint8_t, (*(const uint8_t *)pi - 0x80) << 24)
     195           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float,   AV_SAMPLE_FMT_U8,  uint8_t, (*(const uint8_t *)pi - 0x80) * (1.0f / (1 << 7)))
     196           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double,  AV_SAMPLE_FMT_U8,  uint8_t, (*(const uint8_t *)pi - 0x80) * (1.0  / (1 << 7)))
     197           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8,  uint8_t, AV_SAMPLE_FMT_S16, int16_t, (*(const int16_t *)pi >> 8) + 0x80)
     198           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16, int16_t,  *(const int16_t *)pi)
     199           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16, int16_t,  *(const int16_t *)pi << 16)
     200           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float,   AV_SAMPLE_FMT_S16, int16_t,  *(const int16_t *)pi * (1.0f / (1 << 15)))
     201           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double,  AV_SAMPLE_FMT_S16, int16_t,  *(const int16_t *)pi * (1.0  / (1 << 15)))
     202           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8,  uint8_t, AV_SAMPLE_FMT_S32, int32_t, (*(const int32_t *)pi >> 24) + 0x80)
     203           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32, int32_t,  *(const int32_t *)pi >> 16)
     204           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32, int32_t,  *(const int32_t *)pi)
     205           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float,   AV_SAMPLE_FMT_S32, int32_t,  *(const int32_t *)pi * (1.0f / (1U << 31)))
     206           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double,  AV_SAMPLE_FMT_S32, int32_t,  *(const int32_t *)pi * (1.0  / (1U << 31)))
     207           0 : 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           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float,   av_clip_int16(  lrintf(*(const float *)pi * (1  << 15))))
     209           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float,   av_clipl_int32(llrintf(*(const float *)pi * (1U << 31))))
     210           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float,   AV_SAMPLE_FMT_FLT, float,   *(const float *)pi)
     211           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double,  AV_SAMPLE_FMT_FLT, float,   *(const float *)pi)
     212           0 : 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           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double,  av_clip_int16(  lrint(*(const double *)pi * (1  << 15))))
     214           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double,  av_clipl_int32(llrint(*(const double *)pi * (1U << 31))))
     215           0 : CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float,   AV_SAMPLE_FMT_DBL, double,  *(const double *)pi)
     216           0 : 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           0 : static void set_generic_function(AudioConvert *ac)
     224             : {
     225           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8,  AV_SAMPLE_FMT_U8)
     226           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8)
     227           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8)
     228           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8)
     229           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8)
     230           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8,  AV_SAMPLE_FMT_S16)
     231           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16)
     232           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16)
     233           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16)
     234           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16)
     235           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8,  AV_SAMPLE_FMT_S32)
     236           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32)
     237           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32)
     238           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32)
     239           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32)
     240           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8,  AV_SAMPLE_FMT_FLT)
     241           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT)
     242           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT)
     243           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT)
     244           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT)
     245           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8,  AV_SAMPLE_FMT_DBL)
     246           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL)
     247           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL)
     248           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL)
     249           0 :     SET_CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL)
     250           0 : }
     251             : 
     252           0 : void ff_audio_convert_free(AudioConvert **ac)
     253             : {
     254           0 :     if (!*ac)
     255           0 :         return;
     256           0 :     ff_dither_free(&(*ac)->dc);
     257           0 :     av_freep(ac);
     258             : }
     259             : 
     260           0 : AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr,
     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           0 :     ac = av_mallocz(sizeof(*ac));
     270           0 :     if (!ac)
     271           0 :         return NULL;
     272             : 
     273           0 :     ac->avr      = avr;
     274           0 :     ac->out_fmt  = out_fmt;
     275           0 :     ac->in_fmt   = in_fmt;
     276           0 :     ac->channels = channels;
     277           0 :     ac->apply_map = apply_map;
     278             : 
     279           0 :     if (avr->dither_method != AV_RESAMPLE_DITHER_NONE          &&
     280           0 :         av_get_packed_sample_fmt(out_fmt) == AV_SAMPLE_FMT_S16 &&
     281           0 :         av_get_bytes_per_sample(in_fmt) > 2) {
     282           0 :         ac->dc = ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate,
     283             :                                  apply_map);
     284           0 :         if (!ac->dc) {
     285           0 :             av_free(ac);
     286           0 :             return NULL;
     287             :         }
     288           0 :         return ac;
     289             :     }
     290             : 
     291           0 :     in_planar  = ff_sample_fmt_is_planar(in_fmt, channels);
     292           0 :     out_planar = ff_sample_fmt_is_planar(out_fmt, channels);
     293             : 
     294           0 :     if (in_planar == out_planar) {
     295           0 :         ac->func_type = CONV_FUNC_TYPE_FLAT;
     296           0 :         ac->planes    = in_planar ? ac->channels : 1;
     297           0 :     } else if (in_planar)
     298           0 :         ac->func_type = CONV_FUNC_TYPE_INTERLEAVE;
     299             :     else
     300           0 :         ac->func_type = CONV_FUNC_TYPE_DEINTERLEAVE;
     301             : 
     302           0 :     set_generic_function(ac);
     303             : 
     304             :     if (ARCH_AARCH64)
     305             :         ff_audio_convert_init_aarch64(ac);
     306             :     if (ARCH_ARM)
     307             :         ff_audio_convert_init_arm(ac);
     308             :     if (ARCH_X86)
     309           0 :         ff_audio_convert_init_x86(ac);
     310             : 
     311           0 :     return ac;
     312             : }
     313             : 
     314           0 : int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
     315             : {
     316           0 :     int use_generic = 1;
     317           0 :     int len         = in->nb_samples;
     318             :     int p;
     319             : 
     320           0 :     if (ac->dc) {
     321             :         /* dithered conversion */
     322           0 :         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),
     324             :                 av_get_sample_fmt_name(ac->out_fmt));
     325             : 
     326           0 :         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 */
     331           0 :     if (ac->has_optimized_func) {
     332           0 :         int ptr_align     = FFMIN(in->ptr_align,     out->ptr_align);
     333           0 :         int samples_align = FFMIN(in->samples_align, out->samples_align);
     334           0 :         int aligned_len   = FFALIGN(len, ac->samples_align);
     335           0 :         if (!(ptr_align % ac->ptr_align) && samples_align >= aligned_len) {
     336           0 :             len = aligned_len;
     337           0 :             use_generic = 0;
     338             :         }
     339             :     }
     340           0 :     av_log(ac->avr, AV_LOG_TRACE, "%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);
     344             : 
     345           0 :     if (ac->apply_map) {
     346           0 :         ChannelMapInfo *map = &ac->avr->ch_map_info;
     347             : 
     348           0 :         if (!ff_sample_fmt_is_planar(ac->out_fmt, ac->channels)) {
     349           0 :             av_log(ac->avr, AV_LOG_ERROR, "cannot remap packed format during conversion\n");
     350           0 :             return AVERROR(EINVAL);
     351             :         }
     352             : 
     353           0 :         if (map->do_remap) {
     354           0 :             if (ff_sample_fmt_is_planar(ac->in_fmt, ac->channels)) {
     355           0 :                 conv_func_flat *convert = use_generic ? ac->conv_flat_generic :
     356             :                                                         ac->conv_flat;
     357             : 
     358           0 :                 for (p = 0; p < ac->planes; p++)
     359           0 :                     if (map->channel_map[p] >= 0)
     360           0 :                         convert(out->data[p], in->data[map->channel_map[p]], len);
     361             :             } else {
     362             :                 uint8_t *data[AVRESAMPLE_MAX_CHANNELS];
     363           0 :                 conv_func_deinterleave *convert = use_generic ?
     364           0 :                                                   ac->conv_deinterleave_generic :
     365             :                                                   ac->conv_deinterleave;
     366             : 
     367           0 :                 for (p = 0; p < ac->channels; p++)
     368           0 :                     data[map->input_map[p]] = out->data[p];
     369             : 
     370           0 :                 convert(data, in->data[0], len, ac->channels);
     371             :             }
     372             :         }
     373           0 :         if (map->do_copy || map->do_zero) {
     374           0 :             for (p = 0; p < ac->planes; p++) {
     375           0 :                 if (map->channel_copy[p])
     376           0 :                     memcpy(out->data[p], out->data[map->channel_copy[p]],
     377           0 :                            len * out->stride);
     378           0 :                 else if (map->channel_zero[p])
     379           0 :                     av_samples_set_silence(&out->data[p], 0, len, 1, ac->out_fmt);
     380             :             }
     381             :         }
     382             :     } else {
     383           0 :         switch (ac->func_type) {
     384           0 :         case CONV_FUNC_TYPE_FLAT: {
     385           0 :             if (!in->is_planar)
     386           0 :                 len *= in->channels;
     387           0 :             if (use_generic) {
     388           0 :                 for (p = 0; p < ac->planes; p++)
     389           0 :                     ac->conv_flat_generic(out->data[p], in->data[p], len);
     390             :             } else {
     391           0 :                 for (p = 0; p < ac->planes; p++)
     392           0 :                     ac->conv_flat(out->data[p], in->data[p], len);
     393             :             }
     394           0 :             break;
     395             :         }
     396           0 :         case CONV_FUNC_TYPE_INTERLEAVE:
     397           0 :             if (use_generic)
     398           0 :                 ac->conv_interleave_generic(out->data[0], in->data, len,
     399             :                                             ac->channels);
     400             :             else
     401           0 :                 ac->conv_interleave(out->data[0], in->data, len, ac->channels);
     402           0 :             break;
     403           0 :         case CONV_FUNC_TYPE_DEINTERLEAVE:
     404           0 :             if (use_generic)
     405           0 :                 ac->conv_deinterleave_generic(out->data, in->data[0], len,
     406             :                                               ac->channels);
     407             :             else
     408           0 :                 ac->conv_deinterleave(out->data, in->data[0], len,
     409             :                                       ac->channels);
     410           0 :             break;
     411             :         }
     412             :     }
     413             : 
     414           0 :     out->nb_samples = in->nb_samples;
     415           0 :     return 0;
     416             : }

Generated by: LCOV version 1.13