LCOV - code coverage report
Current view: top level - src/libavcodec - aacdec_fixed.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 84 190 44.2 %
Date: 2017-01-28 02:43:52 Functions: 8 14 57.1 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013
       3             :  *      MIPS Technologies, Inc., California.
       4             :  *
       5             :  * Redistribution and use in source and binary forms, with or without
       6             :  * modification, are permitted provided that the following conditions
       7             :  * are met:
       8             :  * 1. Redistributions of source code must retain the above copyright
       9             :  *    notice, this list of conditions and the following disclaimer.
      10             :  * 2. Redistributions in binary form must reproduce the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer in the
      12             :  *    documentation and/or other materials provided with the distribution.
      13             :  * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
      14             :  *    contributors may be used to endorse or promote products derived from
      15             :  *    this software without specific prior written permission.
      16             :  *
      17             :  * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
      18             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      19             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      20             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
      21             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      22             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      23             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      24             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      25             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      26             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      27             :  * SUCH DAMAGE.
      28             :  *
      29             :  * AAC decoder fixed-point implementation
      30             :  *
      31             :  * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
      32             :  * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
      33             :  *
      34             :  * This file is part of FFmpeg.
      35             :  *
      36             :  * FFmpeg is free software; you can redistribute it and/or
      37             :  * modify it under the terms of the GNU Lesser General Public
      38             :  * License as published by the Free Software Foundation; either
      39             :  * version 2.1 of the License, or (at your option) any later version.
      40             :  *
      41             :  * FFmpeg is distributed in the hope that it will be useful,
      42             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      43             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      44             :  * Lesser General Public License for more details.
      45             :  *
      46             :  * You should have received a copy of the GNU Lesser General Public
      47             :  * License along with FFmpeg; if not, write to the Free Software
      48             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      49             :  */
      50             : 
      51             : /**
      52             :  * @file
      53             :  * AAC decoder
      54             :  * @author Oded Shimon  ( ods15 ods15 dyndns org )
      55             :  * @author Maxim Gavrilov ( maxim.gavrilov gmail com )
      56             :  *
      57             :  * Fixed point implementation
      58             :  * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
      59             :  */
      60             : 
      61             : #define FFT_FLOAT 0
      62             : #define FFT_FIXED_32 1
      63             : #define USE_FIXED 1
      64             : 
      65             : #include "libavutil/fixed_dsp.h"
      66             : #include "libavutil/opt.h"
      67             : #include "avcodec.h"
      68             : #include "internal.h"
      69             : #include "get_bits.h"
      70             : #include "fft.h"
      71             : #include "lpc.h"
      72             : #include "kbdwin.h"
      73             : #include "sinewin.h"
      74             : 
      75             : #include "aac.h"
      76             : #include "aactab.h"
      77             : #include "aacdectab.h"
      78             : #include "cbrt_data.h"
      79             : #include "sbr.h"
      80             : #include "aacsbr.h"
      81             : #include "mpeg4audio.h"
      82             : #include "aacadtsdec.h"
      83             : #include "profiles.h"
      84             : #include "libavutil/intfloat.h"
      85             : 
      86             : #include <math.h>
      87             : #include <string.h>
      88             : 
      89           0 : static av_always_inline void reset_predict_state(PredictorState *ps)
      90             : {
      91           0 :     ps->r0.mant   = 0;
      92           0 :     ps->r0.exp   = 0;
      93           0 :     ps->r1.mant   = 0;
      94           0 :     ps->r1.exp   = 0;
      95           0 :     ps->cor0.mant = 0;
      96           0 :     ps->cor0.exp = 0;
      97           0 :     ps->cor1.mant = 0;
      98           0 :     ps->cor1.exp = 0;
      99           0 :     ps->var0.mant = 0x20000000;
     100           0 :     ps->var0.exp = 1;
     101           0 :     ps->var1.mant = 0x20000000;
     102           0 :     ps->var1.exp = 1;
     103           0 : }
     104             : 
     105             : static const int exp2tab[4] = { Q31(1.0000000000/2), Q31(1.1892071150/2), Q31(1.4142135624/2), Q31(1.6817928305/2) };  // 2^0, 2^0.25, 2^0.5, 2^0.75
     106             : 
     107      668708 : static inline int *DEC_SPAIR(int *dst, unsigned idx)
     108             : {
     109      668708 :     dst[0] = (idx & 15) - 4;
     110      668708 :     dst[1] = (idx >> 4 & 15) - 4;
     111             : 
     112      668708 :     return dst + 2;
     113             : }
     114             : 
     115      975941 : static inline int *DEC_SQUAD(int *dst, unsigned idx)
     116             : {
     117      975941 :     dst[0] = (idx & 3) - 1;
     118      975941 :     dst[1] = (idx >> 2 & 3) - 1;
     119      975941 :     dst[2] = (idx >> 4 & 3) - 1;
     120      975941 :     dst[3] = (idx >> 6 & 3) - 1;
     121             : 
     122      975941 :     return dst + 4;
     123             : }
     124             : 
     125      699408 : static inline int *DEC_UPAIR(int *dst, unsigned idx, unsigned sign)
     126             : {
     127      699408 :     dst[0] = (idx & 15) * (1 - (sign & 0xFFFFFFFE));
     128      699408 :     dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) << 1));
     129             : 
     130      699408 :     return dst + 2;
     131             : }
     132             : 
     133      816171 : static inline int *DEC_UQUAD(int *dst, unsigned idx, unsigned sign)
     134             : {
     135      816171 :     unsigned nz = idx >> 12;
     136             : 
     137      816171 :     dst[0] = (idx & 3) * (1 + (((int)sign >> 31) << 1));
     138      816171 :     sign <<= nz & 1;
     139      816171 :     nz >>= 1;
     140      816171 :     dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) << 1));
     141      816171 :     sign <<= nz & 1;
     142      816171 :     nz >>= 1;
     143      816171 :     dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) << 1));
     144      816171 :     sign <<= nz & 1;
     145      816171 :     nz >>= 1;
     146      816171 :     dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) << 1));
     147             : 
     148      816171 :     return dst + 4;
     149             : }
     150             : 
     151      781110 : static void vector_pow43(int *coefs, int len)
     152             : {
     153             :     int i, coef;
     154             : 
     155    11334454 :     for (i=0; i<len; i++) {
     156    10553344 :         coef = coefs[i];
     157    10553344 :         if (coef < 0)
     158     1828391 :             coef = -(int)ff_cbrt_tab_fixed[-coef];
     159             :         else
     160     8724953 :             coef = (int)ff_cbrt_tab_fixed[coef];
     161    10553344 :         coefs[i] = coef;
     162             :     }
     163      781110 : }
     164             : 
     165      799065 : static void subband_scale(int *dst, int *src, int scale, int offset, int len)
     166             : {
     167      799065 :     int ssign = scale < 0 ? -1 : 1;
     168      799065 :     int s = FFABS(scale);
     169             :     unsigned int round;
     170      799065 :     int i, out, c = exp2tab[s & 3];
     171             : 
     172      799065 :     s = offset - (s >> 2);
     173             : 
     174      799065 :     if (s > 0) {
     175       87590 :         round = 1 << (s-1);
     176     1351498 :         for (i=0; i<len; i++) {
     177     1263908 :             out = (int)(((int64_t)src[i] * c) >> 32);
     178     1263908 :             dst[i] = ((int)(out+round) >> s) * ssign;
     179             :         }
     180             :     }
     181             :     else {
     182      711475 :         s = s + 32;
     183      711475 :         round = 1 << (s-1);
     184    10536111 :         for (i=0; i<len; i++) {
     185     9824636 :             out = (int)((int64_t)((int64_t)src[i] * c + round) >> s);
     186     9824636 :             dst[i] = out * ssign;
     187             :         }
     188             :     }
     189      799065 : }
     190             : 
     191      137931 : static void noise_scale(int *coefs, int scale, int band_energy, int len)
     192             : {
     193      137931 :     int ssign = scale < 0 ? -1 : 1;
     194      137931 :     int s = FFABS(scale);
     195             :     unsigned int round;
     196      137931 :     int i, out, c = exp2tab[s & 3];
     197      137931 :     int nlz = 0;
     198             : 
     199     2285141 :     while (band_energy > 0x7fff) {
     200     2009279 :         band_energy >>= 1;
     201     2009279 :         nlz++;
     202             :     }
     203      137931 :     c /= band_energy;
     204      137931 :     s = 21 + nlz - (s >> 2);
     205             : 
     206      137931 :     if (s > 0) {
     207       67551 :         round = 1 << (s-1);
     208     2331047 :         for (i=0; i<len; i++) {
     209     2263496 :             out = (int)(((int64_t)coefs[i] * c) >> 32);
     210     2263496 :             coefs[i] = ((int)(out+round) >> s) * ssign;
     211             :         }
     212             :     }
     213             :     else {
     214       70380 :         s = s + 32;
     215       70380 :         round = 1 << (s-1);
     216      690360 :         for (i=0; i<len; i++) {
     217      619980 :             out = (int)((int64_t)((int64_t)coefs[i] * c + round) >> s);
     218      619980 :             coefs[i] = out * ssign;
     219             :         }
     220             :     }
     221      137931 : }
     222             : 
     223           0 : static av_always_inline SoftFloat flt16_round(SoftFloat pf)
     224             : {
     225             :     SoftFloat tmp;
     226             :     int s;
     227             : 
     228           0 :     tmp.exp = pf.exp;
     229           0 :     s = pf.mant >> 31;
     230           0 :     tmp.mant = (pf.mant ^ s) - s;
     231           0 :     tmp.mant = (tmp.mant + 0x00200000U) & 0xFFC00000U;
     232           0 :     tmp.mant = (tmp.mant ^ s) - s;
     233             : 
     234           0 :     return tmp;
     235             : }
     236             : 
     237           0 : static av_always_inline SoftFloat flt16_even(SoftFloat pf)
     238             : {
     239             :     SoftFloat tmp;
     240             :     int s;
     241             : 
     242           0 :     tmp.exp = pf.exp;
     243           0 :     s = pf.mant >> 31;
     244           0 :     tmp.mant = (pf.mant ^ s) - s;
     245           0 :     tmp.mant = (tmp.mant + 0x001FFFFFU + (tmp.mant & 0x00400000U >> 16)) & 0xFFC00000U;
     246           0 :     tmp.mant = (tmp.mant ^ s) - s;
     247             : 
     248           0 :     return tmp;
     249             : }
     250             : 
     251           0 : static av_always_inline SoftFloat flt16_trunc(SoftFloat pf)
     252             : {
     253             :     SoftFloat pun;
     254             :     int s;
     255             : 
     256           0 :     pun.exp = pf.exp;
     257           0 :     s = pf.mant >> 31;
     258           0 :     pun.mant = (pf.mant ^ s) - s;
     259           0 :     pun.mant = pun.mant & 0xFFC00000U;
     260           0 :     pun.mant = (pun.mant ^ s) - s;
     261             : 
     262           0 :     return pun;
     263             : }
     264             : 
     265           0 : static av_always_inline void predict(PredictorState *ps, int *coef,
     266             :                                      int output_enable)
     267             : {
     268           0 :     const SoftFloat a     = { 1023410176, 0 };  // 61.0 / 64
     269           0 :     const SoftFloat alpha = {  973078528, 0 };  // 29.0 / 32
     270             :     SoftFloat e0, e1;
     271             :     SoftFloat pv;
     272             :     SoftFloat k1, k2;
     273           0 :     SoftFloat   r0 = ps->r0,     r1 = ps->r1;
     274           0 :     SoftFloat cor0 = ps->cor0, cor1 = ps->cor1;
     275           0 :     SoftFloat var0 = ps->var0, var1 = ps->var1;
     276             :     SoftFloat tmp;
     277             : 
     278           0 :     if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) {
     279           0 :         k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0)));
     280             :     }
     281             :     else {
     282           0 :         k1.mant = 0;
     283           0 :         k1.exp = 0;
     284             :     }
     285             : 
     286           0 :     if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) {
     287           0 :         k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1)));
     288             :     }
     289             :     else {
     290           0 :         k2.mant = 0;
     291           0 :         k2.exp = 0;
     292             :     }
     293             : 
     294           0 :     tmp = av_mul_sf(k1, r0);
     295           0 :     pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1)));
     296           0 :     if (output_enable) {
     297           0 :         int shift = 28 - pv.exp;
     298             : 
     299           0 :         if (shift < 31)
     300           0 :             *coef += (pv.mant + (1 << (shift - 1))) >> shift;
     301             :     }
     302             : 
     303           0 :     e0 = av_int2sf(*coef, 2);
     304           0 :     e1 = av_sub_sf(e0, tmp);
     305             : 
     306           0 :     ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));
     307           0 :     tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));
     308           0 :     tmp.exp--;
     309           0 :     ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));
     310           0 :     ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));
     311           0 :     tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));
     312           0 :     tmp.exp--;
     313           0 :     ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));
     314             : 
     315           0 :     ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));
     316           0 :     ps->r0 = flt16_trunc(av_mul_sf(a, e0));
     317           0 : }
     318             : 
     319             : 
     320             : static const int cce_scale_fixed[8] = {
     321             :     Q30(1.0),          //2^(0/8)
     322             :     Q30(1.0905077327), //2^(1/8)
     323             :     Q30(1.1892071150), //2^(2/8)
     324             :     Q30(1.2968395547), //2^(3/8)
     325             :     Q30(1.4142135624), //2^(4/8)
     326             :     Q30(1.5422108254), //2^(5/8)
     327             :     Q30(1.6817928305), //2^(6/8)
     328             :     Q30(1.8340080864), //2^(7/8)
     329             : };
     330             : 
     331             : /**
     332             :  * Apply dependent channel coupling (applied before IMDCT).
     333             :  *
     334             :  * @param   index   index into coupling gain array
     335             :  */
     336           0 : static void apply_dependent_coupling_fixed(AACContext *ac,
     337             :                                      SingleChannelElement *target,
     338             :                                      ChannelElement *cce, int index)
     339             : {
     340           0 :     IndividualChannelStream *ics = &cce->ch[0].ics;
     341           0 :     const uint16_t *offsets = ics->swb_offset;
     342           0 :     int *dest = target->coeffs;
     343           0 :     const int *src = cce->ch[0].coeffs;
     344           0 :     int g, i, group, k, idx = 0;
     345           0 :     if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
     346           0 :         av_log(ac->avctx, AV_LOG_ERROR,
     347             :                "Dependent coupling is not supported together with LTP\n");
     348           0 :         return;
     349             :     }
     350           0 :     for (g = 0; g < ics->num_window_groups; g++) {
     351           0 :         for (i = 0; i < ics->max_sfb; i++, idx++) {
     352           0 :             if (cce->ch[0].band_type[idx] != ZERO_BT) {
     353           0 :                 const int gain = cce->coup.gain[index][idx];
     354             :                 int shift, round, c, tmp;
     355             : 
     356           0 :                 if (gain < 0) {
     357           0 :                     c = -cce_scale_fixed[-gain & 7];
     358           0 :                     shift = (-gain-1024) >> 3;
     359             :                 }
     360             :                 else {
     361           0 :                     c = cce_scale_fixed[gain & 7];
     362           0 :                     shift = (gain-1024) >> 3;
     363             :                 }
     364             : 
     365           0 :                 if (shift < 0) {
     366           0 :                     shift = -shift;
     367           0 :                     round = 1 << (shift - 1);
     368             : 
     369           0 :                     for (group = 0; group < ics->group_len[g]; group++) {
     370           0 :                         for (k = offsets[i]; k < offsets[i + 1]; k++) {
     371           0 :                             tmp = (int)(((int64_t)src[group * 128 + k] * c + \
     372           0 :                                        (int64_t)0x1000000000) >> 37);
     373           0 :                             dest[group * 128 + k] += (tmp + round) >> shift;
     374             :                         }
     375             :                     }
     376             :                 }
     377             :                 else {
     378           0 :                     for (group = 0; group < ics->group_len[g]; group++) {
     379           0 :                         for (k = offsets[i]; k < offsets[i + 1]; k++) {
     380           0 :                             tmp = (int)(((int64_t)src[group * 128 + k] * c + \
     381           0 :                                         (int64_t)0x1000000000) >> 37);
     382           0 :                             dest[group * 128 + k] += tmp << shift;
     383             :                         }
     384             :                     }
     385             :                 }
     386             :             }
     387             :         }
     388           0 :         dest += ics->group_len[g] * 128;
     389           0 :         src  += ics->group_len[g] * 128;
     390             :     }
     391             : }
     392             : 
     393             : /**
     394             :  * Apply independent channel coupling (applied after IMDCT).
     395             :  *
     396             :  * @param   index   index into coupling gain array
     397             :  */
     398         650 : static void apply_independent_coupling_fixed(AACContext *ac,
     399             :                                        SingleChannelElement *target,
     400             :                                        ChannelElement *cce, int index)
     401             : {
     402             :     int i, c, shift, round, tmp;
     403         650 :     const int gain = cce->coup.gain[index][0];
     404         650 :     const int *src = cce->ch[0].ret;
     405         650 :     int *dest = target->ret;
     406         650 :     const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
     407             : 
     408         650 :     c = cce_scale_fixed[gain & 7];
     409         650 :     shift = (gain-1024) >> 3;
     410         650 :     if (shift < 0) {
     411           0 :         shift = -shift;
     412           0 :         round = 1 << (shift - 1);
     413             : 
     414           0 :         for (i = 0; i < len; i++) {
     415           0 :             tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
     416           0 :             dest[i] += (tmp + round) >> shift;
     417             :         }
     418             :     }
     419             :     else {
     420      666250 :       for (i = 0; i < len; i++) {
     421      665600 :           tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
     422      665600 :           dest[i] += tmp << shift;
     423             :       }
     424             :     }
     425         650 : }
     426             : 
     427             : #include "aacdec_template.c"
     428             : 
     429             : AVCodec ff_aac_fixed_decoder = {
     430             :     .name            = "aac_fixed",
     431             :     .long_name       = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
     432             :     .type            = AVMEDIA_TYPE_AUDIO,
     433             :     .id              = AV_CODEC_ID_AAC,
     434             :     .priv_data_size  = sizeof(AACContext),
     435             :     .init            = aac_decode_init,
     436             :     .close           = aac_decode_close,
     437             :     .decode          = aac_decode_frame,
     438             :     .sample_fmts     = (const enum AVSampleFormat[]) {
     439             :         AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
     440             :     },
     441             :     .capabilities    = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
     442             :     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE,
     443             :     .channel_layouts = aac_channel_layout,
     444             :     .profiles        = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
     445             :     .flush = flush,
     446             : };

Generated by: LCOV version 1.12