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

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2004 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 "libavutil/common.h"
      23             : #include "libavutil/libm.h"
      24             : #include "libavutil/log.h"
      25             : #include "internal.h"
      26             : #include "resample.h"
      27             : #include "audio_data.h"
      28             : 
      29             : 
      30             : /* double template */
      31             : #define CONFIG_RESAMPLE_DBL
      32             : #include "resample_template.c"
      33             : #undef CONFIG_RESAMPLE_DBL
      34             : 
      35             : /* float template */
      36             : #define CONFIG_RESAMPLE_FLT
      37             : #include "resample_template.c"
      38             : #undef CONFIG_RESAMPLE_FLT
      39             : 
      40             : /* s32 template */
      41             : #define CONFIG_RESAMPLE_S32
      42             : #include "resample_template.c"
      43             : #undef CONFIG_RESAMPLE_S32
      44             : 
      45             : /* s16 template */
      46             : #include "resample_template.c"
      47             : 
      48             : 
      49             : /* 0th order modified Bessel function of the first kind. */
      50           0 : static double bessel(double x)
      51             : {
      52           0 :     double v     = 1;
      53           0 :     double lastv = 0;
      54           0 :     double t     = 1;
      55             :     int i;
      56             : 
      57           0 :     x = x * x / 4;
      58           0 :     for (i = 1; v != lastv; i++) {
      59           0 :         lastv = v;
      60           0 :         t    *= x / (i * i);
      61           0 :         v    += t;
      62             :     }
      63           0 :     return v;
      64             : }
      65             : 
      66             : /* Build a polyphase filterbank. */
      67           0 : static int build_filter(ResampleContext *c, double factor)
      68             : {
      69             :     int ph, i;
      70             :     double x, y, w;
      71             :     double *tab;
      72           0 :     int tap_count    = c->filter_length;
      73           0 :     int phase_count  = 1 << c->phase_shift;
      74           0 :     const int center = (tap_count - 1) / 2;
      75             : 
      76           0 :     tab = av_malloc(tap_count * sizeof(*tab));
      77           0 :     if (!tab)
      78           0 :         return AVERROR(ENOMEM);
      79             : 
      80           0 :     for (ph = 0; ph < phase_count; ph++) {
      81           0 :         double norm = 0;
      82           0 :         for (i = 0; i < tap_count; i++) {
      83           0 :             x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
      84           0 :             if (x == 0) y = 1.0;
      85           0 :             else        y = sin(x) / x;
      86           0 :             switch (c->filter_type) {
      87           0 :             case AV_RESAMPLE_FILTER_TYPE_CUBIC: {
      88           0 :                 const float d = -0.5; //first order derivative = -0.5
      89           0 :                 x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
      90           0 :                 if (x < 1.0) y = 1 - 3 * x*x + 2 * x*x*x + d * (                -x*x + x*x*x);
      91           0 :                 else         y =                           d * (-4 + 8 * x - 5 * x*x + x*x*x);
      92           0 :                 break;
      93             :             }
      94           0 :             case AV_RESAMPLE_FILTER_TYPE_BLACKMAN_NUTTALL:
      95           0 :                 w  = 2.0 * x / (factor * tap_count) + M_PI;
      96           0 :                 y *= 0.3635819 - 0.4891775 * cos(    w) +
      97           0 :                                  0.1365995 * cos(2 * w) -
      98           0 :                                  0.0106411 * cos(3 * w);
      99           0 :                 break;
     100           0 :             case AV_RESAMPLE_FILTER_TYPE_KAISER:
     101           0 :                 w  = 2.0 * x / (factor * tap_count * M_PI);
     102           0 :                 y *= bessel(c->kaiser_beta * sqrt(FFMAX(1 - w * w, 0)));
     103           0 :                 break;
     104             :             }
     105             : 
     106           0 :             tab[i] = y;
     107           0 :             norm  += y;
     108             :         }
     109             :         /* normalize so that an uniform color remains the same */
     110           0 :         for (i = 0; i < tap_count; i++)
     111           0 :             tab[i] = tab[i] / norm;
     112             : 
     113           0 :         c->set_filter(c->filter_bank, tab, ph, tap_count);
     114             :     }
     115             : 
     116           0 :     av_free(tab);
     117           0 :     return 0;
     118             : }
     119             : 
     120           0 : ResampleContext *ff_audio_resample_init(AVAudioResampleContext *avr)
     121             : {
     122             :     ResampleContext *c;
     123           0 :     int out_rate    = avr->out_sample_rate;
     124           0 :     int in_rate     = avr->in_sample_rate;
     125           0 :     double factor   = FFMIN(out_rate * avr->cutoff / in_rate, 1.0);
     126           0 :     int phase_count = 1 << avr->phase_shift;
     127             :     int felem_size;
     128             : 
     129           0 :     if (avr->internal_sample_fmt != AV_SAMPLE_FMT_S16P &&
     130           0 :         avr->internal_sample_fmt != AV_SAMPLE_FMT_S32P &&
     131           0 :         avr->internal_sample_fmt != AV_SAMPLE_FMT_FLTP &&
     132           0 :         avr->internal_sample_fmt != AV_SAMPLE_FMT_DBLP) {
     133           0 :         av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
     134             :                "resampling: %s\n",
     135             :                av_get_sample_fmt_name(avr->internal_sample_fmt));
     136           0 :         return NULL;
     137             :     }
     138           0 :     c = av_mallocz(sizeof(*c));
     139           0 :     if (!c)
     140           0 :         return NULL;
     141             : 
     142           0 :     c->avr           = avr;
     143           0 :     c->phase_shift   = avr->phase_shift;
     144           0 :     c->phase_mask    = phase_count - 1;
     145           0 :     c->linear        = avr->linear_interp;
     146           0 :     c->filter_length = FFMAX((int)ceil(avr->filter_size / factor), 1);
     147           0 :     c->filter_type   = avr->filter_type;
     148           0 :     c->kaiser_beta   = avr->kaiser_beta;
     149             : 
     150           0 :     switch (avr->internal_sample_fmt) {
     151           0 :     case AV_SAMPLE_FMT_DBLP:
     152           0 :         c->resample_one  = c->linear ? resample_linear_dbl : resample_one_dbl;
     153           0 :         c->resample_nearest = resample_nearest_dbl;
     154           0 :         c->set_filter    = set_filter_dbl;
     155           0 :         break;
     156           0 :     case AV_SAMPLE_FMT_FLTP:
     157           0 :         c->resample_one  = c->linear ? resample_linear_flt : resample_one_flt;
     158           0 :         c->resample_nearest = resample_nearest_flt;
     159           0 :         c->set_filter    = set_filter_flt;
     160           0 :         break;
     161           0 :     case AV_SAMPLE_FMT_S32P:
     162           0 :         c->resample_one  = c->linear ? resample_linear_s32 : resample_one_s32;
     163           0 :         c->resample_nearest = resample_nearest_s32;
     164           0 :         c->set_filter    = set_filter_s32;
     165           0 :         break;
     166           0 :     case AV_SAMPLE_FMT_S16P:
     167           0 :         c->resample_one  = c->linear ? resample_linear_s16 : resample_one_s16;
     168           0 :         c->resample_nearest = resample_nearest_s16;
     169           0 :         c->set_filter    = set_filter_s16;
     170           0 :         break;
     171             :     }
     172             : 
     173             :     if (ARCH_AARCH64)
     174             :         ff_audio_resample_init_aarch64(c, avr->internal_sample_fmt);
     175             :     if (ARCH_ARM)
     176             :         ff_audio_resample_init_arm(c, avr->internal_sample_fmt);
     177             : 
     178           0 :     felem_size = av_get_bytes_per_sample(avr->internal_sample_fmt);
     179           0 :     c->filter_bank = av_mallocz(c->filter_length * (phase_count + 1) * felem_size);
     180           0 :     if (!c->filter_bank)
     181           0 :         goto error;
     182             : 
     183           0 :     if (build_filter(c, factor) < 0)
     184           0 :         goto error;
     185             : 
     186           0 :     memcpy(&c->filter_bank[(c->filter_length * phase_count + 1) * felem_size],
     187           0 :            c->filter_bank, (c->filter_length - 1) * felem_size);
     188           0 :     memcpy(&c->filter_bank[c->filter_length * phase_count * felem_size],
     189           0 :            &c->filter_bank[(c->filter_length - 1) * felem_size], felem_size);
     190             : 
     191           0 :     c->compensation_distance = 0;
     192           0 :     if (!av_reduce(&c->src_incr, &c->dst_incr, out_rate,
     193           0 :                    in_rate * (int64_t)phase_count, INT32_MAX / 2))
     194           0 :         goto error;
     195           0 :     c->ideal_dst_incr = c->dst_incr;
     196             : 
     197           0 :     c->padding_size   = (c->filter_length - 1) / 2;
     198           0 :     c->initial_padding_filled = 0;
     199           0 :     c->index = 0;
     200           0 :     c->frac  = 0;
     201             : 
     202             :     /* allocate internal buffer */
     203           0 :     c->buffer = ff_audio_data_alloc(avr->resample_channels, c->padding_size,
     204             :                                     avr->internal_sample_fmt,
     205             :                                     "resample buffer");
     206           0 :     if (!c->buffer)
     207           0 :         goto error;
     208           0 :     c->buffer->nb_samples      = c->padding_size;
     209           0 :     c->initial_padding_samples = c->padding_size;
     210             : 
     211           0 :     av_log(avr, AV_LOG_DEBUG, "resample: %s from %d Hz to %d Hz\n",
     212             :            av_get_sample_fmt_name(avr->internal_sample_fmt),
     213             :            avr->in_sample_rate, avr->out_sample_rate);
     214             : 
     215           0 :     return c;
     216             : 
     217           0 : error:
     218           0 :     ff_audio_data_free(&c->buffer);
     219           0 :     av_free(c->filter_bank);
     220           0 :     av_free(c);
     221           0 :     return NULL;
     222             : }
     223             : 
     224           0 : void ff_audio_resample_free(ResampleContext **c)
     225             : {
     226           0 :     if (!*c)
     227           0 :         return;
     228           0 :     ff_audio_data_free(&(*c)->buffer);
     229           0 :     av_free((*c)->filter_bank);
     230           0 :     av_freep(c);
     231             : }
     232             : 
     233           0 : int avresample_set_compensation(AVAudioResampleContext *avr, int sample_delta,
     234             :                                 int compensation_distance)
     235             : {
     236             :     ResampleContext *c;
     237             : 
     238           0 :     if (compensation_distance < 0)
     239           0 :         return AVERROR(EINVAL);
     240           0 :     if (!compensation_distance && sample_delta)
     241           0 :         return AVERROR(EINVAL);
     242             : 
     243           0 :     if (!avr->resample_needed) {
     244           0 :         av_log(avr, AV_LOG_ERROR, "Unable to set resampling compensation\n");
     245           0 :         return AVERROR(EINVAL);
     246             :     }
     247           0 :     c = avr->resample;
     248           0 :     c->compensation_distance = compensation_distance;
     249           0 :     if (compensation_distance) {
     250           0 :         c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr *
     251           0 :                       (int64_t)sample_delta / compensation_distance;
     252             :     } else {
     253           0 :         c->dst_incr = c->ideal_dst_incr;
     254             :     }
     255             : 
     256           0 :     return 0;
     257             : }
     258             : 
     259           0 : static int resample(ResampleContext *c, void *dst, const void *src,
     260             :                     int *consumed, int src_size, int dst_size, int update_ctx,
     261             :                     int nearest_neighbour)
     262             : {
     263             :     int dst_index;
     264           0 :     unsigned int index = c->index;
     265           0 :     int frac          = c->frac;
     266           0 :     int dst_incr_frac = c->dst_incr % c->src_incr;
     267           0 :     int dst_incr      = c->dst_incr / c->src_incr;
     268           0 :     int compensation_distance = c->compensation_distance;
     269             : 
     270           0 :     if (!dst != !src)
     271           0 :         return AVERROR(EINVAL);
     272             : 
     273           0 :     if (nearest_neighbour) {
     274           0 :         uint64_t index2 = ((uint64_t)index) << 32;
     275           0 :         int64_t incr   = (1LL << 32) * c->dst_incr / c->src_incr;
     276           0 :         dst_size       = FFMIN(dst_size,
     277             :                                (src_size-1-index) * (int64_t)c->src_incr /
     278             :                                c->dst_incr);
     279             : 
     280           0 :         if (dst) {
     281           0 :             for(dst_index = 0; dst_index < dst_size; dst_index++) {
     282           0 :                 c->resample_nearest(dst, dst_index, src, index2 >> 32);
     283           0 :                 index2 += incr;
     284             :             }
     285             :         } else {
     286           0 :             dst_index = dst_size;
     287             :         }
     288           0 :         index += dst_index * dst_incr;
     289           0 :         index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
     290           0 :         frac   = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
     291             :     } else {
     292           0 :         for (dst_index = 0; dst_index < dst_size; dst_index++) {
     293           0 :             int sample_index = index >> c->phase_shift;
     294             : 
     295           0 :             if (sample_index + c->filter_length > src_size)
     296           0 :                 break;
     297             : 
     298           0 :             if (dst)
     299           0 :                 c->resample_one(c, dst, dst_index, src, index, frac);
     300             : 
     301           0 :             frac  += dst_incr_frac;
     302           0 :             index += dst_incr;
     303           0 :             if (frac >= c->src_incr) {
     304           0 :                 frac -= c->src_incr;
     305           0 :                 index++;
     306             :             }
     307           0 :             if (dst_index + 1 == compensation_distance) {
     308           0 :                 compensation_distance = 0;
     309           0 :                 dst_incr_frac = c->ideal_dst_incr % c->src_incr;
     310           0 :                 dst_incr      = c->ideal_dst_incr / c->src_incr;
     311             :             }
     312             :         }
     313             :     }
     314           0 :     if (consumed)
     315           0 :         *consumed = index >> c->phase_shift;
     316             : 
     317           0 :     if (update_ctx) {
     318           0 :         index &= c->phase_mask;
     319             : 
     320           0 :         if (compensation_distance) {
     321           0 :             compensation_distance -= dst_index;
     322           0 :             if (compensation_distance <= 0)
     323           0 :                 return AVERROR_BUG;
     324             :         }
     325           0 :         c->frac     = frac;
     326           0 :         c->index    = index;
     327           0 :         c->dst_incr = dst_incr_frac + c->src_incr*dst_incr;
     328           0 :         c->compensation_distance = compensation_distance;
     329             :     }
     330             : 
     331           0 :     return dst_index;
     332             : }
     333             : 
     334           0 : int ff_audio_resample(ResampleContext *c, AudioData *dst, AudioData *src)
     335             : {
     336           0 :     int ch, in_samples, in_leftover, consumed = 0, out_samples = 0;
     337           0 :     int ret = AVERROR(EINVAL);
     338           0 :     int nearest_neighbour = (c->compensation_distance == 0 &&
     339           0 :                              c->filter_length == 1 &&
     340           0 :                              c->phase_shift == 0);
     341             : 
     342           0 :     in_samples  = src ? src->nb_samples : 0;
     343           0 :     in_leftover = c->buffer->nb_samples;
     344             : 
     345             :     /* add input samples to the internal buffer */
     346           0 :     if (src) {
     347           0 :         ret = ff_audio_data_combine(c->buffer, in_leftover, src, 0, in_samples);
     348           0 :         if (ret < 0)
     349           0 :             return ret;
     350           0 :     } else if (in_leftover <= c->final_padding_samples) {
     351             :         /* no remaining samples to flush */
     352           0 :         return 0;
     353             :     }
     354             : 
     355           0 :     if (!c->initial_padding_filled) {
     356           0 :         int bps = av_get_bytes_per_sample(c->avr->internal_sample_fmt);
     357             :         int i;
     358             : 
     359           0 :         if (src && c->buffer->nb_samples < 2 * c->padding_size)
     360           0 :             return 0;
     361             : 
     362           0 :         for (i = 0; i < c->padding_size; i++)
     363           0 :             for (ch = 0; ch < c->buffer->channels; ch++) {
     364           0 :                 if (c->buffer->nb_samples > 2 * c->padding_size - i) {
     365           0 :                     memcpy(c->buffer->data[ch] + bps * i,
     366           0 :                            c->buffer->data[ch] + bps * (2 * c->padding_size - i), bps);
     367             :                 } else {
     368           0 :                     memset(c->buffer->data[ch] + bps * i, 0, bps);
     369             :                 }
     370             :             }
     371           0 :         c->initial_padding_filled = 1;
     372             :     }
     373             : 
     374           0 :     if (!src && !c->final_padding_filled) {
     375           0 :         int bps = av_get_bytes_per_sample(c->avr->internal_sample_fmt);
     376             :         int i;
     377             : 
     378           0 :         ret = ff_audio_data_realloc(c->buffer,
     379           0 :                                     FFMAX(in_samples, in_leftover) +
     380           0 :                                     c->padding_size);
     381           0 :         if (ret < 0) {
     382           0 :             av_log(c->avr, AV_LOG_ERROR, "Error reallocating resampling buffer\n");
     383           0 :             return AVERROR(ENOMEM);
     384             :         }
     385             : 
     386           0 :         for (i = 0; i < c->padding_size; i++)
     387           0 :             for (ch = 0; ch < c->buffer->channels; ch++) {
     388           0 :                 if (in_leftover > i) {
     389           0 :                     memcpy(c->buffer->data[ch] + bps * (in_leftover + i),
     390           0 :                            c->buffer->data[ch] + bps * (in_leftover - i - 1),
     391             :                            bps);
     392             :                 } else {
     393           0 :                     memset(c->buffer->data[ch] + bps * (in_leftover + i),
     394             :                            0, bps);
     395             :                 }
     396             :             }
     397           0 :         c->buffer->nb_samples   += c->padding_size;
     398           0 :         c->final_padding_samples = c->padding_size;
     399           0 :         c->final_padding_filled  = 1;
     400             :     }
     401             : 
     402             : 
     403             :     /* calculate output size and reallocate output buffer if needed */
     404             :     /* TODO: try to calculate this without the dummy resample() run */
     405           0 :     if (!dst->read_only && dst->allow_realloc) {
     406           0 :         out_samples = resample(c, NULL, NULL, NULL, c->buffer->nb_samples,
     407             :                                INT_MAX, 0, nearest_neighbour);
     408           0 :         ret = ff_audio_data_realloc(dst, out_samples);
     409           0 :         if (ret < 0) {
     410           0 :             av_log(c->avr, AV_LOG_ERROR, "error reallocating output\n");
     411           0 :             return ret;
     412             :         }
     413             :     }
     414             : 
     415             :     /* resample each channel plane */
     416           0 :     for (ch = 0; ch < c->buffer->channels; ch++) {
     417           0 :         out_samples = resample(c, (void *)dst->data[ch],
     418           0 :                                (const void *)c->buffer->data[ch], &consumed,
     419           0 :                                c->buffer->nb_samples, dst->allocated_samples,
     420           0 :                                ch + 1 == c->buffer->channels, nearest_neighbour);
     421             :     }
     422           0 :     if (out_samples < 0) {
     423           0 :         av_log(c->avr, AV_LOG_ERROR, "error during resampling\n");
     424           0 :         return out_samples;
     425             :     }
     426             : 
     427             :     /* drain consumed samples from the internal buffer */
     428           0 :     ff_audio_data_drain(c->buffer, consumed);
     429           0 :     c->initial_padding_samples = FFMAX(c->initial_padding_samples - consumed, 0);
     430             : 
     431           0 :     av_log(c->avr, AV_LOG_TRACE, "resampled %d in + %d leftover to %d out + %d leftover\n",
     432           0 :             in_samples, in_leftover, out_samples, c->buffer->nb_samples);
     433             : 
     434           0 :     dst->nb_samples = out_samples;
     435           0 :     return 0;
     436             : }
     437             : 
     438           0 : int avresample_get_delay(AVAudioResampleContext *avr)
     439             : {
     440           0 :     ResampleContext *c = avr->resample;
     441             : 
     442           0 :     if (!avr->resample_needed || !avr->resample)
     443           0 :         return 0;
     444             : 
     445           0 :     return FFMAX(c->buffer->nb_samples - c->padding_size, 0);
     446             : }

Generated by: LCOV version 1.13