LCOV - code coverage report
Current view: top level - libavcodec - aacdec_fixed.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 87 202 43.1 %
Date: 2017-12-16 13:57:32 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 "adts_header.h"
      79             : #include "cbrt_data.h"
      80             : #include "sbr.h"
      81             : #include "aacsbr.h"
      82             : #include "mpeg4audio.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      672272 : static inline int *DEC_SPAIR(int *dst, unsigned idx)
     108             : {
     109      672272 :     dst[0] = (idx & 15) - 4;
     110      672272 :     dst[1] = (idx >> 4 & 15) - 4;
     111             : 
     112      672272 :     return dst + 2;
     113             : }
     114             : 
     115      978157 : static inline int *DEC_SQUAD(int *dst, unsigned idx)
     116             : {
     117      978157 :     dst[0] = (idx & 3) - 1;
     118      978157 :     dst[1] = (idx >> 2 & 3) - 1;
     119      978157 :     dst[2] = (idx >> 4 & 3) - 1;
     120      978157 :     dst[3] = (idx >> 6 & 3) - 1;
     121             : 
     122      978157 :     return dst + 4;
     123             : }
     124             : 
     125      703742 : static inline int *DEC_UPAIR(int *dst, unsigned idx, unsigned sign)
     126             : {
     127      703742 :     dst[0] = (idx & 15) * (1 - (sign & 0xFFFFFFFE));
     128      703742 :     dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) * 2));
     129             : 
     130      703742 :     return dst + 2;
     131             : }
     132             : 
     133      816691 : static inline int *DEC_UQUAD(int *dst, unsigned idx, unsigned sign)
     134             : {
     135      816691 :     unsigned nz = idx >> 12;
     136             : 
     137      816691 :     dst[0] = (idx & 3) * (1 + (((int)sign >> 31) * 2));
     138      816691 :     sign <<= nz & 1;
     139      816691 :     nz >>= 1;
     140      816691 :     dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) * 2));
     141      816691 :     sign <<= nz & 1;
     142      816691 :     nz >>= 1;
     143      816691 :     dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) * 2));
     144      816691 :     sign <<= nz & 1;
     145      816691 :     nz >>= 1;
     146      816691 :     dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) * 2));
     147             : 
     148      816691 :     return dst + 4;
     149             : }
     150             : 
     151      787858 : static void vector_pow43(int *coefs, int len)
     152             : {
     153             :     int i, coef;
     154             : 
     155    11368194 :     for (i=0; i<len; i++) {
     156    10580336 :         coef = coefs[i];
     157    10580336 :         if (coef < 0)
     158     1834713 :             coef = -(int)ff_cbrt_tab_fixed[-coef];
     159             :         else
     160     8745623 :             coef = (int)ff_cbrt_tab_fixed[coef];
     161    10580336 :         coefs[i] = coef;
     162             :     }
     163      787858 : }
     164             : 
     165      805813 : static void subband_scale(int *dst, int *src, int scale, int offset, int len)
     166             : {
     167      805813 :     int ssign = scale < 0 ? -1 : 1;
     168      805813 :     int s = FFABS(scale);
     169             :     unsigned int round;
     170      805813 :     int i, out, c = exp2tab[s & 3];
     171             : 
     172      805813 :     s = offset - (s >> 2);
     173             : 
     174      805813 :     if (s > 31) {
     175           0 :         for (i=0; i<len; i++) {
     176           0 :             dst[i] = 0;
     177             :         }
     178      805813 :     } else if (s > 0) {
     179       94338 :         round = 1 << (s-1);
     180     1385238 :         for (i=0; i<len; i++) {
     181     1290900 :             out = (int)(((int64_t)src[i] * c) >> 32);
     182     1290900 :             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      805813 : }
     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 :             if (shift > 0) {
     310           0 :                 *coef += (unsigned)((pv.mant + (1 << (shift - 1))) >> shift);
     311             :             } else
     312           0 :                 *coef += (unsigned)pv.mant << -shift;
     313             :         }
     314             :     }
     315             : 
     316           0 :     e0 = av_int2sf(*coef, 2);
     317           0 :     e1 = av_sub_sf(e0, tmp);
     318             : 
     319           0 :     ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));
     320           0 :     tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));
     321           0 :     tmp.exp--;
     322           0 :     ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));
     323           0 :     ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));
     324           0 :     tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));
     325           0 :     tmp.exp--;
     326           0 :     ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));
     327             : 
     328           0 :     ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));
     329           0 :     ps->r0 = flt16_trunc(av_mul_sf(a, e0));
     330           0 : }
     331             : 
     332             : 
     333             : static const int cce_scale_fixed[8] = {
     334             :     Q30(1.0),          //2^(0/8)
     335             :     Q30(1.0905077327), //2^(1/8)
     336             :     Q30(1.1892071150), //2^(2/8)
     337             :     Q30(1.2968395547), //2^(3/8)
     338             :     Q30(1.4142135624), //2^(4/8)
     339             :     Q30(1.5422108254), //2^(5/8)
     340             :     Q30(1.6817928305), //2^(6/8)
     341             :     Q30(1.8340080864), //2^(7/8)
     342             : };
     343             : 
     344             : /**
     345             :  * Apply dependent channel coupling (applied before IMDCT).
     346             :  *
     347             :  * @param   index   index into coupling gain array
     348             :  */
     349           0 : static void apply_dependent_coupling_fixed(AACContext *ac,
     350             :                                      SingleChannelElement *target,
     351             :                                      ChannelElement *cce, int index)
     352             : {
     353           0 :     IndividualChannelStream *ics = &cce->ch[0].ics;
     354           0 :     const uint16_t *offsets = ics->swb_offset;
     355           0 :     int *dest = target->coeffs;
     356           0 :     const int *src = cce->ch[0].coeffs;
     357           0 :     int g, i, group, k, idx = 0;
     358           0 :     if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
     359           0 :         av_log(ac->avctx, AV_LOG_ERROR,
     360             :                "Dependent coupling is not supported together with LTP\n");
     361           0 :         return;
     362             :     }
     363           0 :     for (g = 0; g < ics->num_window_groups; g++) {
     364           0 :         for (i = 0; i < ics->max_sfb; i++, idx++) {
     365           0 :             if (cce->ch[0].band_type[idx] != ZERO_BT) {
     366           0 :                 const int gain = cce->coup.gain[index][idx];
     367             :                 int shift, round, c, tmp;
     368             : 
     369           0 :                 if (gain < 0) {
     370           0 :                     c = -cce_scale_fixed[-gain & 7];
     371           0 :                     shift = (-gain-1024) >> 3;
     372             :                 }
     373             :                 else {
     374           0 :                     c = cce_scale_fixed[gain & 7];
     375           0 :                     shift = (gain-1024) >> 3;
     376             :                 }
     377             : 
     378           0 :                 if (shift < -31) {
     379             :                     // Nothing to do
     380           0 :                 } else if (shift < 0) {
     381           0 :                     shift = -shift;
     382           0 :                     round = 1 << (shift - 1);
     383             : 
     384           0 :                     for (group = 0; group < ics->group_len[g]; group++) {
     385           0 :                         for (k = offsets[i]; k < offsets[i + 1]; k++) {
     386           0 :                             tmp = (int)(((int64_t)src[group * 128 + k] * c + \
     387           0 :                                        (int64_t)0x1000000000) >> 37);
     388           0 :                             dest[group * 128 + k] += (tmp + round) >> shift;
     389             :                         }
     390             :                     }
     391             :                 }
     392             :                 else {
     393           0 :                     for (group = 0; group < ics->group_len[g]; group++) {
     394           0 :                         for (k = offsets[i]; k < offsets[i + 1]; k++) {
     395           0 :                             tmp = (int)(((int64_t)src[group * 128 + k] * c + \
     396           0 :                                         (int64_t)0x1000000000) >> 37);
     397           0 :                             dest[group * 128 + k] += tmp * (1U << shift);
     398             :                         }
     399             :                     }
     400             :                 }
     401             :             }
     402             :         }
     403           0 :         dest += ics->group_len[g] * 128;
     404           0 :         src  += ics->group_len[g] * 128;
     405             :     }
     406             : }
     407             : 
     408             : /**
     409             :  * Apply independent channel coupling (applied after IMDCT).
     410             :  *
     411             :  * @param   index   index into coupling gain array
     412             :  */
     413         650 : static void apply_independent_coupling_fixed(AACContext *ac,
     414             :                                        SingleChannelElement *target,
     415             :                                        ChannelElement *cce, int index)
     416             : {
     417             :     int i, c, shift, round, tmp;
     418         650 :     const int gain = cce->coup.gain[index][0];
     419         650 :     const int *src = cce->ch[0].ret;
     420         650 :     int *dest = target->ret;
     421         650 :     const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
     422             : 
     423         650 :     c = cce_scale_fixed[gain & 7];
     424         650 :     shift = (gain-1024) >> 3;
     425         650 :     if (shift < -31) {
     426           0 :         return;
     427         650 :     } else if (shift < 0) {
     428           0 :         shift = -shift;
     429           0 :         round = 1 << (shift - 1);
     430             : 
     431           0 :         for (i = 0; i < len; i++) {
     432           0 :             tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
     433           0 :             dest[i] += (tmp + round) >> shift;
     434             :         }
     435             :     }
     436             :     else {
     437      666250 :       for (i = 0; i < len; i++) {
     438      665600 :           tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
     439      665600 :           dest[i] += tmp * (1 << shift);
     440             :       }
     441             :     }
     442             : }
     443             : 
     444             : #include "aacdec_template.c"
     445             : 
     446             : AVCodec ff_aac_fixed_decoder = {
     447             :     .name            = "aac_fixed",
     448             :     .long_name       = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
     449             :     .type            = AVMEDIA_TYPE_AUDIO,
     450             :     .id              = AV_CODEC_ID_AAC,
     451             :     .priv_data_size  = sizeof(AACContext),
     452             :     .init            = aac_decode_init,
     453             :     .close           = aac_decode_close,
     454             :     .decode          = aac_decode_frame,
     455             :     .sample_fmts     = (const enum AVSampleFormat[]) {
     456             :         AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
     457             :     },
     458             :     .capabilities    = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
     459             :     .caps_internal   = FF_CODEC_CAP_INIT_THREADSAFE,
     460             :     .channel_layouts = aac_channel_layout,
     461             :     .profiles        = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
     462             :     .flush = flush,
     463             : };

Generated by: LCOV version 1.13