Home | History | Annotate | Download | only in aacdec
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /*
     19 
     20  Pathname: huffdecode.c
     21 
     22 ------------------------------------------------------------------------------
     23  REVISION HISTORY
     24 
     25  Description:  Modified from original shareware code
     26 
     27  Description:  Modified to pass variables by reference to eliminate use
     28                of global variables.
     29 
     30  Description:  Change variable types.
     31 
     32  Description:  (1) Modified to bring in-line with PV standards.
     33                (2) Eliminated global_gain on stack,
     34                    getics() has to define this parameter on its stack.
     35                (3) Eliminated multiple returns
     36                (4) Altered return logic of getics()
     37                (5) Convert Real coef -> Int32 coef
     38                (6) Move BITS *pInputStream to 2nd parameter of huffdecode.c
     39                    and getics.c
     40                (7) Pass pFrameInfo per channel, because two channels can have
     41                    different windows
     42 
     43  Description: (1) Eliminated function call to chn_config
     44               (2) Eliminate widx calculation
     45               (3) copy channel info from left to right when common_window
     46                   is enabled
     47               (4) add error checking of getmask return value
     48 
     49  Description:  Change default_position to current_program
     50 
     51  Description:  Remove prstflag
     52 
     53  Description:  Modify call to get_ics_info
     54 
     55  Description:  Modified so getmask is NOT called if the status returned
     56  from get_ics_info indicates an error.
     57 
     58  Description:
     59  (1) Added include of "e_ElementId.h"
     60      Previously, this function was relying on another include file
     61      to include e_ElementId.h
     62 
     63  (2) Updated the copyright header.
     64 
     65  Description:  Modified to include usage of the new "shared memory" structures
     66  defined in s_tDec_Int_File.h and s_tDec_Int_Chan.h
     67 
     68  Description:
     69  (1) Updated to reflect the fact that the temporary FrameInfo used by getics.c
     70  was moved into the region of memory shared with fxpCoef.
     71 
     72  Description:
     73  (1) Removed first parameter to getics.  The temporary FrameInfo was
     74      unnecessary.
     75 
     76  Description: Replace some instances of getbits to get9_n_lessbits
     77               when the number of bits read is 9 or less and get1bits
     78               when only 1 bit is read.
     79 
     80  Description: Relaxed tag verification. Some encoder do not match the tag
     81               to the channel ID (as the standard request to differentiate
     82               different channel), in our wireless work, with only mono
     83               or stereo channel, this become restrictive to some encoders
     84 
     85 
     86  Description:
     87 
     88 ------------------------------------------------------------------------------
     89  INPUT AND OUTPUT DEFINITIONS
     90 
     91  Inputs:
     92 
     93     id_syn_ele  = identification flag for channel syntactic element, Int
     94 
     95     pInputStream= pointer to input bitstream, BITS.
     96 
     97     pVars       = pointer to structure that holds information for decoding,
     98                   tDec_Int_File
     99 
    100     pChVars[]   = pointer to structure that holds channel information,
    101                   tDec_Int_Chan
    102 
    103 
    104  Local Stores/Buffers/Pointers Needed:
    105     None
    106 
    107  Global Stores/Buffers/Pointers Needed:
    108     None
    109 
    110  Outputs:
    111     status = 0  if success
    112              non-zero  otherwise
    113 
    114  Pointers and Buffers Modified:
    115     pChVars->sect   contents updated by newly decoded section information
    116                     of current frame
    117 
    118     pChVars->factors contents updated by newly decoded scalefactors
    119 
    120     pChVars->ch_coef contents updated by newly decoded spectral coefficients
    121 
    122     PChVars->tns    contents updated by newly decoded TNS information
    123 
    124     pVars->hasmask  contents updated by newly decoded Mid/Side mask
    125                     information
    126 
    127     pVars->pulseInfo contents updated by newly decoded pulse data information
    128 
    129  Local Stores Modified:
    130     None
    131 
    132  Global Stores Modified:
    133     None
    134 
    135 ------------------------------------------------------------------------------
    136  FUNCTION DESCRIPTION
    137 
    138   This function offers a framework for decoding the data of the next 1024
    139   samples. It maps the channel configuration according to the id_syn_ele flag,
    140   configures the channel information, and calls getics to do huffman decoding
    141   The function returns 1 if there was an error
    142 
    143 ------------------------------------------------------------------------------
    144  REQUIREMENTS
    145 
    146  This function should set up the channel configuration for huffman decoding
    147 
    148 ------------------------------------------------------------------------------
    149  REFERENCES
    150 
    151  (1) MPEG-2 NBC Audio Decoder
    152    "This software module was originally developed by AT&T, Dolby
    153    Laboratories, Fraunhofer Gesellschaft IIS in the course of development
    154    of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
    155    3. This software module is an implementation of a part of one or more
    156    MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
    157    Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audio
    158    standards free license to this software module or modifications thereof
    159    for use in hardware or software products claiming conformance to the
    160    MPEG-2 NBC/MPEG-4 Audio  standards. Those intending to use this software
    161    module in hardware or software products are advised that this use may
    162    infringe existing patents. The original developer of this software
    163    module and his/her company, the subsequent editors and their companies,
    164    and ISO/IEC have no liability for use of this software module or
    165    modifications thereof in an implementation. Copyright is not released
    166    for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
    167    developer retains full right to use the code for his/her own purpose,
    168    assign or donate the code to a third party and to inhibit third party
    169    from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
    170    This copyright notice must be included in all copies or derivative
    171    works."
    172    Copyright(c)1996.
    173 
    174  (2) ISO/IEC 14496-3: 1999(E)
    175     Subpart 4       p15     (single_channel_element, channel_pair_element)
    176                     p15     (Table 4.4.5    getmask)
    177                     p16     (Table 4.4.6    get_ics_info)
    178                     p24     (Table 4.4.24   getics)
    179 
    180 ------------------------------------------------------------------------------
    181  PSEUDO-CODE
    182 
    183     tag = CALL getbits(LEN_TAG,pInputStream)
    184                 MODIFYING(pInputStream)
    185                 RETURNING(tag)
    186 
    187     common_window = 0;
    188 
    189     IF (id_syn_ele == ID_CPE)
    190     THEN
    191         common_window = CALL getbits(LEN_COM_WIN,pInputStream);
    192                                 MODIFYING(pInputStream)
    193                                 RETURNING(common_window)
    194     ENDIF
    195 
    196     pMcInfo = &pVars->mc_info;
    197 
    198     IF ( (pMcInfo->ch_info[0].cpe != id_syn_ele) OR
    199          (pMcInfo->ch_info[0].tag != tag) )
    200     THEN
    201         status = 1;
    202     ENDIF
    203 
    204 
    205     IF (status == SUCCESS)
    206     THEN
    207         IF (id_syn_ele == ID_SCE)
    208         THEN
    209 
    210             leftCh  = 0;
    211             RIGHT = 0;
    212             pChVars[leftCh]->hasmask = 0;
    213         ELSEIF (id_syn_ele == ID_CPE)
    214 
    215             leftCh = 0;
    216             rightCh  = 1;
    217 
    218             IF (common_window != FALSE)
    219             THEN
    220 
    221                 CALL get_ics_info(
    222                         audioObjectType = pVars->mc_info.audioObjectType,
    223                         pInputStream = pInputStream,
    224                         common_window = common_window,
    225                         pWindowSequence = &pChVars[leftCh]->wnd,
    226                         &pChVars[leftCh]->wnd_shape_this_bk,
    227                         pChVars[leftCh]->group,
    228                         &pChVars[leftCh]->max_sfb,
    229                         pVars->winmap,
    230                         &pChVars[leftCh]->lt_status,
    231                         &pChVars[rightCh]->lt_status);
    232                      MODIFYING(pInputStream, wnd, wnd_shape_this_bk,group,
    233                                max_sfb, lt_status)
    234                      RETURNING(status)
    235 
    236                 IF (status == SUCCESS)
    237                 THEN
    238 
    239                     pChVars[rightCh]->wnd = pChVars[leftCh]->wnd;
    240                     pChVars[rightCh]->wnd_shape_this_bk =
    241                         pChVars[leftCh]->wnd_shape_this_bk;
    242                     pChVars[rightCh]->max_sfb = pChVars[leftCh]->max_sfb;
    243                     pv_memcpy(
    244                         pChVars[rightCh]->group,
    245                         pChVars[leftCh]->group,
    246                         NSHORT*sizeof(pChVars[leftCh]->group[0]));
    247 
    248                     hasmask = CALL getmask(
    249                                     pVars->winmap[pChVars[leftCh]->wnd],
    250                                     pInputStream,
    251                                     pChVars[leftCh]->group,
    252                                     pChVars[leftCh]->max_sfb,
    253                                     pChVars[leftCh]->mask);
    254                                 MODIFYING(pInputStream, mask)
    255                                 RETURNING(hasmask)
    256 
    257                     IF (hasmask == MASK_ERROR)
    258                     THEN
    259                         status = 1;
    260                     ENDIF
    261                     pChVars[leftCh]->hasmask  = hasmask;
    262                     pChVars[rightCh]->hasmask = hasmask;
    263 
    264                 ENDIF
    265 
    266             ELSE
    267 
    268                  pChVars[leftCh]->hasmask  = 0;
    269                  pChVars[rightCh]->hasmask = 0;
    270             ENDIF(common_window)
    271 
    272         ENDIF(id_syn_ele)
    273 
    274     ENDIF (status)
    275 
    276     ch = leftCh;
    277 
    278     WHILE((ch <= rightCh) AND (status == SUCCESS))
    279 
    280         status = CALL getics(
    281                         pInputStream,
    282                         common_window,
    283                         pVars,
    284                         pChVars[ch],
    285                         pChVars[ch]->group,
    286                         &pChVars[ch]->max_sfb,
    287                         pChVars[ch]->cb_map,
    288                         &pChVars[ch]->tns,
    289                         pVars->winmap,
    290                         &pVars->pulseInfo,
    291                         pChVars[ch]->sect);
    292                     MODIFYING(pInputStream,pVarsp,ChVars[ch],group,
    293                               max_sfb,tns,pulseInfo,sect)
    294                     RETURNING(status)
    295 
    296         ch++;
    297 
    298     ENDWHILE
    299 
    300     RETURN status;
    301 
    302 ------------------------------------------------------------------------------
    303  RESOURCES USED
    304    When the code is written for a specific target processor the
    305      the resources used should be documented below.
    306 
    307  STACK USAGE: [stack count for this module] + [variable to represent
    308           stack usage for each subroutine called]
    309 
    310      where: [stack usage variable] = stack usage for [subroutine
    311          name] (see [filename].ext)
    312 
    313  DATA MEMORY USED: x words
    314 
    315  PROGRAM MEMORY USED: x words
    316 
    317  CLOCK CYCLES: [cycle count equation for this module] + [variable
    318            used to represent cycle count for each subroutine
    319            called]
    320 
    321      where: [cycle count variable] = cycle count for [subroutine
    322         name] (see [filename].ext)
    323 
    324 ------------------------------------------------------------------------------
    325 */
    326 
    327 
    328 /*----------------------------------------------------------------------------
    329 ; INCLUDES
    330 ----------------------------------------------------------------------------*/
    331 #include    "pv_audio_type_defs.h"
    332 #include    "aac_mem_funcs.h"
    333 #include    "huffman.h"
    334 #include    "e_maskstatus.h"
    335 #include    "e_elementid.h"
    336 #include    "get_ics_info.h"
    337 
    338 /*----------------------------------------------------------------------------
    339 ; MACROS
    340 ; Define module specific macros here
    341 ----------------------------------------------------------------------------*/
    342 
    343 /*----------------------------------------------------------------------------
    344 ; DEFINES
    345 ; Include all pre-processor statements here. Include conditional
    346 ; compile variables also.
    347 ----------------------------------------------------------------------------*/
    348 #define LEFT  (0)
    349 #define RIGHT (1)
    350 /*----------------------------------------------------------------------------
    351 ; LOCAL FUNCTION DEFINITIONS
    352 ; Function Prototype declaration
    353 ----------------------------------------------------------------------------*/
    354 
    355 /*----------------------------------------------------------------------------
    356 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
    357 ; Variable declaration - defined here and used outside this module
    358 ----------------------------------------------------------------------------*/
    359 
    360 /*----------------------------------------------------------------------------
    361 ; EXTERNAL FUNCTION REFERENCES
    362 ; Declare functions defined elsewhere and referenced in this module
    363 ----------------------------------------------------------------------------*/
    364 
    365 /*----------------------------------------------------------------------------
    366 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
    367 ; Declare variables used in this module but defined elsewhere
    368 ----------------------------------------------------------------------------*/
    369 
    370 /*----------------------------------------------------------------------------
    371 ; FUNCTION CODE
    372 ----------------------------------------------------------------------------*/
    373 Int huffdecode(
    374     Int           id_syn_ele,
    375     BITS          *pInputStream,
    376     tDec_Int_File *pVars,
    377     tDec_Int_Chan *pChVars[])
    378 
    379 {
    380     /*----------------------------------------------------------------------------
    381     ; Define all local variables
    382     ----------------------------------------------------------------------------*/
    383     Int      ch;
    384     Int      common_window;
    385     Int      hasmask;
    386     Int      status   = SUCCESS;
    387     Int      num_channels = 0;
    388     MC_Info  *pMcInfo;
    389 
    390     per_chan_share_w_fxpCoef *pChLeftShare;  /* Helper pointer */
    391     per_chan_share_w_fxpCoef *pChRightShare; /* Helper pointer */
    392     /*----------------------------------------------------------------------------
    393     ; Function body here
    394     ----------------------------------------------------------------------------*/
    395 
    396     get9_n_lessbits(
    397         LEN_TAG,
    398         pInputStream);
    399 
    400     /* suppose an un-supported id_syn_ele will never be passed */
    401 
    402     common_window = 0;
    403 
    404     if (id_syn_ele == ID_CPE)
    405     {
    406         common_window =
    407             get1bits(pInputStream);
    408     }
    409 
    410     pMcInfo = &pVars->mc_info;
    411 
    412     /*
    413      *  check if provided info (num of channels) on audio config,
    414      *  matches read bitstream data, if not, allow update only once.
    415      *  In almost all cases it should match.
    416      */
    417     if ((pMcInfo->ch_info[0].cpe != id_syn_ele))
    418     {
    419         if (pVars->mc_info.implicit_channeling)     /* check done only once */
    420         {
    421             pMcInfo->ch_info[0].cpe = id_syn_ele & 1; /*  collect info from bitstream
    422                                                      *  implicit_channeling flag is locked
    423                                                      *  after 1st frame, to avoid toggling
    424                                                      *  parameter in the middle of the clip
    425                                                      */
    426             pMcInfo->nch = (id_syn_ele & 1) + 1;     /* update number of channels */
    427         }
    428         else
    429         {
    430             status = 1; /* ERROR break if syntax error persist  */
    431         }
    432     }
    433 
    434     if (status == SUCCESS)
    435     {
    436         if (id_syn_ele == ID_SCE)
    437         {
    438 
    439             num_channels = 1;
    440             pVars->hasmask = 0;
    441         }
    442         else if (id_syn_ele == ID_CPE)
    443         {
    444             pChLeftShare = pChVars[LEFT]->pShareWfxpCoef;
    445             pChRightShare = pChVars[RIGHT]->pShareWfxpCoef;
    446             num_channels = 2;
    447 
    448             if (common_window != FALSE)
    449             {
    450 
    451                 status = get_ics_info(
    452                              (tMP4AudioObjectType) pVars->mc_info.audioObjectType,
    453                              pInputStream,
    454                              (Bool)common_window,
    455                              (WINDOW_SEQUENCE *) & pChVars[LEFT]->wnd,
    456                              (WINDOW_SHAPE *) & pChVars[LEFT]->wnd_shape_this_bk,
    457                              pChLeftShare->group,
    458                              (Int *) & pChLeftShare->max_sfb,
    459                              pVars->winmap,
    460                              (LT_PRED_STATUS *) & pChLeftShare->lt_status,
    461                              (LT_PRED_STATUS *) & pChRightShare->lt_status);
    462 
    463                 if (status == SUCCESS)
    464                 {
    465                     /* copy left channel info to right channel */
    466                     pChVars[RIGHT]->wnd = pChVars[LEFT]->wnd;
    467                     pChVars[RIGHT]->wnd_shape_this_bk =
    468                         pChVars[LEFT]->wnd_shape_this_bk;
    469                     pChRightShare->max_sfb = pChLeftShare->max_sfb;
    470                     pv_memcpy(
    471                         pChRightShare->group,
    472                         pChLeftShare->group,
    473                         NSHORT*sizeof(pChLeftShare->group[0]));
    474 
    475                     hasmask = getmask(
    476                                   pVars->winmap[pChVars[LEFT]->wnd],
    477                                   pInputStream,
    478                                   pChLeftShare->group,
    479                                   pChLeftShare->max_sfb,
    480                                   pVars->mask);
    481 
    482                     if (hasmask == MASK_ERROR)
    483                     {
    484                         status = 1; /* ERROR code */
    485                     }
    486                     pVars->hasmask  = hasmask;
    487 
    488                 } /* if (status == 0) */
    489             }
    490             else
    491             {
    492                 pVars->hasmask  = 0;
    493             } /* if (common_window) */
    494 
    495         } /* if (id_syn_ele) */
    496 
    497     } /* if (status) */
    498 
    499     ch = 0;
    500     while ((ch < num_channels) && (status == SUCCESS))
    501     {
    502         pChLeftShare = pChVars[ch]->pShareWfxpCoef;
    503 
    504         status = getics(
    505                      pInputStream,
    506                      common_window,
    507                      pVars,
    508                      pChVars[ch],
    509                      pChLeftShare->group,
    510                      &pChLeftShare->max_sfb,
    511                      pChLeftShare->cb_map,
    512                      &pChLeftShare->tns,
    513                      pVars->winmap,
    514                      &pVars->share.a.pulseInfo,
    515                      pVars->share.a.sect);
    516 
    517         ch++;
    518 
    519     } /* while (ch) */
    520 
    521     /*----------------------------------------------------------------------------
    522     ; Return status
    523     ----------------------------------------------------------------------------*/
    524 
    525     return status;
    526 
    527 } /* huffdecode */
    528 
    529