LCOV - code coverage report
Current view: top level - src/libavcodec - aacdec_fixed.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 87 200 43.5 %
Date: 2017-06-23 19:00:59 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) * 2));
     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) * 2));
     138      816171 :     sign <<= nz & 1;
     139      816171 :     nz >>= 1;
     140      816171 :     dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) * 2));
     141      816171 :     sign <<= nz & 1;
     142      816171 :     nz >>= 1;
     143      816171 :     dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) * 2));
     144      816171 :     sign <<= nz & 1;
     145      816171 :     nz >>= 1;
     146      816171 :     dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) * 2));
     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 > 31) {
     175           0 :         for (i=0; i<len; i++) {
     176           0 :             dst[i] = 0;
     177             :         }
     178      799065 :     } else if (s > 0) {
     179       87590 :         round = 1 << (s-1);
     180     1351498 :         for (i=0; i<len; i++) {
     181     1263908 :             out = (int)(((int64_t)src[i] * c) >> 32);
     182     1263908 :             dst[i] = ((int)(out+round) >> s) * ssign;
     183             :         }
     184      711475 :     } else if (s > -32) {
     185      711475 :         s = s + 32;
     186      711475 :         round = 1U << (s-1);
     187    10536111 :         for (i=0; i<len; i++) {
     188     9824636 :             out = (int)((int64_t)((int64_t)src[i] * c + round) >> s);
     189     9824636 :             dst[i] = out * (unsigned)ssign;
     190             :         }
     191             :     } else {
     192           0 :         av_log(NULL, AV_LOG_ERROR, "Overflow in subband_scale()\n");
     193             :     }
     194      799065 : }
     195             : 
     196      137931 : static void noise_scale(int *coefs, int scale, int band_energy, int len)
     197             : {
     198      137931 :     int ssign = scale < 0 ? -1 : 1;
     199      137931 :     int s = FFABS(scale);
     200             :     unsigned int round;
     201      137931 :     int i, out, c = exp2tab[s & 3];
     202      137931 :     int nlz = 0;
     203             : 
     204     2285141 :     while (band_energy > 0x7fff) {
     205     2009279 :         band_energy >>= 1;
     206     2009279 :         nlz++;
     207             :     }
     208      137931 :     c /= band_energy;
     209      137931 :     s = 21 + nlz - (s >> 2);
     210             : 
     211      137931 :     if (s > 31) {
     212           0 :         for (i=0; i<len; i++) {
     213           0 :             coefs[i] = 0;
     214             :         }
     215      137931 :     } else if (s >= 0) {
     216       73177 :         round = s ? 1 << (s-1) : 0;
     217     2460461 :         for (i=0; i<len; i++) {
     218     2387284 :             out = (int)(((int64_t)coefs[i] * c) >> 32);
     219     2387284 :             coefs[i] = ((int)(out+round) >> s) * ssign;
     220             :         }
     221             :     }
     222             :     else {
     223       64754 :         s = s + 32;
     224       64754 :         round = 1 << (s-1);
     225      560946 :         for (i=0; i<len; i++) {
     226      496192 :             out = (int)((int64_t)((int64_t)coefs[i] * c + round) >> s);
     227      496192 :             coefs[i] = out * ssign;
     228             :         }
     229             :     }
     230      137931 : }
     231             : 
     232           0 : static av_always_inline SoftFloat flt16_round(SoftFloat pf)
     233             : {
     234             :     SoftFloat tmp;
     235             :     int s;
     236             : 
     237           0 :     tmp.exp = pf.exp;
     238           0 :     s = pf.mant >> 31;
     239           0 :     tmp.mant = (pf.mant ^ s) - s;
     240           0 :     tmp.mant = (tmp.mant + 0x00200000U) & 0xFFC00000U;
     241           0 :     tmp.mant = (tmp.mant ^ s) - s;
     242             : 
     243           0 :     return tmp;
     244             : }
     245             : 
     246           0 : static av_always_inline SoftFloat flt16_even(SoftFloat pf)
     247             : {
     248             :     SoftFloat tmp;
     249             :     int s;
     250             : 
     251           0 :     tmp.exp = pf.exp;
     252           0 :     s = pf.mant >> 31;
     253           0 :     tmp.mant = (pf.mant ^ s) - s;
     254           0 :     tmp.mant = (tmp.mant + 0x001FFFFFU + (tmp.mant & 0x00400000U >> 16)) & 0xFFC00000U;
     255           0 :     tmp.mant = (tmp.mant ^ s) - s;
     256             : 
     257           0 :     return tmp;
     258             : }
     259             : 
     260           0 : static av_always_inline SoftFloat flt16_trunc(SoftFloat pf)
     261             : {
     262             :     SoftFloat pun;
     263             :     int s;
     264             : 
     265           0 :     pun.exp = pf.exp;
     266           0 :     s = pf.mant >> 31;
     267           0 :     pun.mant = (pf.mant ^ s) - s;
     268           0 :     pun.mant = pun.mant & 0xFFC00000U;
     269           0 :     pun.mant = (pun.mant ^ s) - s;
     270             : 
     271           0 :     return pun;
     272             : }
     273             : 
     274           0 : static av_always_inline void predict(PredictorState *ps, int *coef,
     275             :                                      int output_enable)
     276             : {
     277           0 :     const SoftFloat a     = { 1023410176, 0 };  // 61.0 / 64
     278           0 :     const SoftFloat alpha = {  973078528, 0 };  // 29.0 / 32
     279             :     SoftFloat e0, e1;
     280             :     SoftFloat pv;
     281             :     SoftFloat k1, k2;
     282           0 :     SoftFloat   r0 = ps->r0,     r1 = ps->r1;
     283           0 :     SoftFloat cor0 = ps->cor0, cor1 = ps->cor1;
     284           0 :     SoftFloat var0 = ps->var0, var1 = ps->var1;
     285             :     SoftFloat tmp;
     286             : 
     287           0 :     if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) {
     288           0 :         k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0)));
     289             :     }
     290             :     else {
     291           0 :         k1.mant = 0;
     292           0 :         k1.exp = 0;
     293             :     }
     294             : 
     295           0 :     if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) {
     296           0 :         k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1)));
     297             :     }
     298             :     else {
     299           0 :         k2.mant = 0;
     300           0 :         k2.exp = 0;
     301             :     }
     302             : 
     303           0 :     tmp = av_mul_sf(k1, r0);
     304           0 :     pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1)));
     305           0 :     if (output_enable) {
     306           0 :         int shift = 28 - pv.exp;
     307             : 
     308           0 :         if (shift < 31)
     309           0 :             *coef += (pv.mant + (1 << (shift - 1))) >> shift;
     310             :     }
     311             : 
     312           0 :     e0 = av_int2sf(*coef, 2);
     313           0 :     e1 = av_sub_sf(e0, tmp);
     314             : 
     315           0 :     ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));
     316           0 :     tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));
     317           0 :     tmp.exp--;
     318           0 :     ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));
     319           0 :     ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));
     320           0 :     tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));
     321           0 :     tmp.exp--;
     322           0 :     ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));
     323             : 
     324           0 :     ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));
     325           0 :     ps->r0 = flt16_trunc(av_mul_sf(a, e0));
     326           0 : }
     327             : 
     328             : 
     329             : static const int cce_scale_fixed[8] = {
     330             :     Q30(1.0),          //2^(0/8)
     331             :     Q30(1.0905077327), //2^(1/8)
     332             :     Q30(1.1892071150), //2^(2/8)
     333             :     Q30(1.2968395547), //2^(3/8)
     334             :     Q30(1.4142135624), //2^(4/8)
     335             :     Q30(1.5422108254), //2^(5/8)
     336             :     Q30(1.6817928305), //2^(6/8)
     337             :     Q30(1.8340080864), //2^(7/8)
     338             : };
     339             : 
     340             : /**
     341             :  * Apply dependent channel coupling (applied before IMDCT).
     342             :  *
     343             :  * @param   index   index into coupling gain array
     344             :  */
     345           0 : static void apply_dependent_coupling_fixed(AACContext *ac,
     346             :                                      SingleChannelElement *target,
     347             :                                      ChannelElement *cce, int index)
     348             : {
     349           0 :     IndividualChannelStream *ics = &cce->ch[0].ics;
     350           0 :     const uint16_t *offsets = ics->swb_offset;
     351           0 :     int *dest = target->coeffs;
     352           0 :     const int *src = cce->ch[0].coeffs;
     353           0 :     int g, i, group, k, idx = 0;
     354           0 :     if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
     355           0 :         av_log(ac->avctx, AV_LOG_ERROR,
     356             :                "Dependent coupling is not supported together with LTP\n");
     357           0 :         return;
     358             :     }
     359           0 :     for (g = 0; g < ics->num_window_groups; g++) {
     360           0 :         for (i = 0; i < ics->max_sfb; i++, idx++) {
     361           0 :             if (cce->ch[0].band_type[idx] != ZERO_BT) {
     362           0 :                 const int gain = cce->coup.gain[index][idx];
     363             :                 int shift, round, c, tmp;
     364             : 
     365           0 :                 if (gain < 0) {
     366           0 :                     c = -cce_scale_fixed[-gain & 7];
     367           0 :                     shift = (-gain-1024) >> 3;
     368             :                 }
     369             :                 else {
     370           0 :                     c = cce_scale_fixed[gain & 7];
     371           0 :                     shift = (gain-1024) >> 3;
     372             :                 }
     373             : 
     374           0 :                 if (shift < -31) {
     375             :                     // Nothing to do
     376           0 :                 } else if (shift < 0) {
     377           0 :                     shift = -shift;
     378           0 :                     round = 1 << (shift - 1);
     379             : 
     380           0 :                     for (group = 0; group < ics->group_len[g]; group++) {
     381           0 :                         for (k = offsets[i]; k < offsets[i + 1]; k++) {
     382           0 :                             tmp = (int)(((int64_t)src[group * 128 + k] * c + \
     383           0 :                                        (int64_t)0x1000000000) >> 37);
     384           0 :                             dest[group * 128 + k] += (tmp + round) >> shift;
     385             :                         }
     386             :                     }
     387             :                 }
     388             :                 else {
     389           0 :                     for (group = 0; group < ics->group_len[g]; group++) {
     390           0 :                         for (k = offsets[i]; k < offsets[i + 1]; k++) {
     391           0 :                             tmp = (int)(((int64_t)src[group * 128 + k] * c + \
     392           0 :                                         (int64_t)0x1000000000) >> 37);
     393           0 :                             dest[group * 128 + k] += tmp * (1 << shift);
     394             :                         }
     395             :                     }
     396             :                 }
     397             :             }
     398             :         }
     399           0 :         dest += ics->group_len[g] * 128;
     400           0 :         src  += ics->group_len[g] * 128;
     401             :     }
     402             : }
     403             : 
     404             : /**
     405             :  * Apply independent channel coupling (applied after IMDCT).
     406             :  *
     407             :  * @param   index   index into coupling gain array
     408             :  */
     409         650 : static void apply_independent_coupling_fixed(AACContext *ac,
     410             :                                        SingleChannelElement *target,
     411             :                                        ChannelElement *cce, int index)
     412             : {
     413             :     int i, c, shift, round, tmp;
     414         650 :     const int gain = cce->coup.gain[index][0];
     415         650 :     const int *src = cce->ch[0].ret;
     416         650 :     int *dest = target->ret;
     417         650 :     const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
     418             : 
     419         650 :     c = cce_scale_fixed[gain & 7];
     420         650 :     shift = (gain-1024) >> 3;
     421         650 :     if (shift < -31) {
     422           0 :         return;
     423         650 :     } else if (shift < 0) {
     424           0 :         shift = -shift;
     425           0 :         round = 1 << (shift - 1);
     426             : 
     427           0 :         for (i = 0; i < len; i++) {
     428           0 :             tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
     429           0 :             dest[i] += (tmp + round) >> shift;
     430             :         }
     431             :     }
     432             :     else {
     433      666250 :       for (i = 0; i < len; i++) {
     434      665600 :           tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
     435      665600 :           dest[i] += tmp << shift;
     436             :       }
     437             :     }
     438             : }
     439             : 
     440             : #include "aacdec_template.c"
     441             : 
     442             : AVCodec ff_aac_fixed_decoder = {
     443             :     .name            = "aac_fixed",
     444             :     .long_name       = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
     445             :     .type            = AVMEDIA_TYPE_AUDIO,
     446             :     .id              = AV_CODEC_ID_AAC,
     447             :     .priv_data_size  = sizeof(AACContext),
     448             :     .init            = aac_decode_init,
     449             :     .close           = aac_decode_close,
     450             :     .decode          = aac_decode_frame,
     451             :     .sample_fmts     = (const enum AVSampleFormat[]) {
     452             :         AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
     453             :     },
     454             :     .capabilities    = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
     455             :     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE,
     456             :     .channel_layouts = aac_channel_layout,
     457             :     .profiles        = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
     458             :     .flush = flush,
     459             : };

Generated by: LCOV version 1.13