summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/aacdec/hufffac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/aacdec/hufffac.cpp')
-rw-r--r--media/libstagefright/codecs/aacdec/hufffac.cpp550
1 files changed, 550 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/hufffac.cpp b/media/libstagefright/codecs/aacdec/hufffac.cpp
new file mode 100644
index 0000000..e5a9c59
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/hufffac.cpp
@@ -0,0 +1,550 @@
+/* ------------------------------------------------------------------
+ * Copyright (C) 1998-2009 PacketVideo
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ * -------------------------------------------------------------------
+ */
+/*
+
+ Pathname: ./src/hufffac.c
+ Funtions:
+ hufffac
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Modified from original shareware code
+
+ Description: Modified to pass variables by reference to eliminate use
+ of global variables.
+
+ Description: (1) Modified with new templates,
+ (2) Modified variable names for clarity
+ (3) adjusted variables of "for loop"
+ (4) eliminated multiple returns, use return valid
+
+ Description: (1) Change return logic: 0 if success, 1 if error
+ (2) Define SectInfo structure to store section codebook index
+ and section boundary
+ (3) Substitute "switch" with "if- else if"
+ (4) move BITS *pInputStream to second pass-in parameter
+ (5) pass in huffBookUsed[] to save stack size
+
+ Description: (1) Remove pass in parameter Hcb pBook
+
+ Description: Use binary tree search in decode_huff_cw_binary
+
+ Description: Use decode_huff_scl function.
+
+ Who: Date: MM/DD/YYYY
+ Description:
+
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+
+ *pFrameInfo = pointer to structure that holds information
+ of each Frame. type FrameInfo
+
+ *pInputStream = pointer to input bitstream. type BITS
+
+ *pGroup = pointer to array that contains the index of the first
+ window in each group, type UChar
+
+ nsect = number of sections to be decoded. type Int
+
+ *pSect = pointer to structure array that contains the huffman
+ codebook index and section boundary for each section,
+ type SectInfo
+
+ global_gain = initial value for "DPCM encoded" scalefactors and noise
+ energy, type Int
+
+ *pFactors = pointer to array that stores the decoded scalefactors,
+ intensity position or noise energy, type Int
+
+ huffBookUsed = array that will hold the huffman codebook index for
+ each sfb, type Int
+
+ *pBook = pointer to structure that contains the huffman codebook
+ information, such as dimension, Largest Absolute Value
+ (LAV) of each huffman codebook, etc. type Hcb
+
+
+ Local Stores/Buffers/Pointers Needed: None
+
+ Global Stores/Buffers/Pointers Needed: None
+
+ Outputs:
+ 0 if success
+ 1 if error
+
+ Pointers and Buffers Modified:
+
+ Int *pFactors contains the newly decoded scalefactors and/or
+ intensity position and/or noise energy level
+
+ Local Stores Modified:
+
+ Global Stores Modified:
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function first reads the Huffman codebook index of all sections within
+ one Frame. Then, depending on the huffman codebook index of each section,
+ the function decodes the scalefactors, and/or intensity positions
+ (INTENSITY_HCB, INTENSITY_HCB2), and/or noise energy (NOISE_HCB)
+ for every scalefactor band in each section.
+ The function returns 0 upon successful decoding, returns 1 if error.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ This function should replace the content of the array pFactors with the
+ decoded scalefactors and/or intensity positions and/or noise energy
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ (1) MPEG-2 NBC Audio Decoder
+ "This software module was originally developed by AT&T, Dolby
+ Laboratories, Fraunhofer Gesellschaft IIS in the course of development
+ of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and
+ 3. This software module is an implementation of a part of one or more
+ MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4
+ Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio
+ standards free license to this software module or modifications thereof
+ for use in hardware or software products claiming conformance to the
+ MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software
+ module in hardware or software products are advised that this use may
+ infringe existing patents. The original developer of this software
+ module and his/her company, the subsequent editors and their companies,
+ and ISO/IEC have no liability for use of this software module or
+ modifications thereof in an implementation. Copyright is not released
+ for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original
+ developer retains full right to use the code for his/her own purpose,
+ assign or donate the code to a third party and to inhibit third party
+ from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products.
+ This copyright notice must be included in all copies or derivative
+ works."
+ Copyright(c)1996.
+
+ (2) ISO/IEC 14496-3: 1999(E)
+ Subpart 4 p72-73 (scalefactors)
+ p76 (decoding)
+ p78 (Table 4.6.1, Table 4.6.2)
+ p93-94 (INTENSITY_HCB)
+ p123 (NOISE_HCB)
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+ status = SUCCESS;
+
+ CALL pv_memset(pHuffBookUsed, ZERO_HCB, MAXBANDS*sizeof(*pHuffBookUsed));
+
+ CALL pv_memset(pFactors, ZERO_HCB, MAXBANDS*sizeof(*pFactors));
+
+ sect_start = 0;
+
+ FOR(sect_idx = nsect; sect_idx > 0; sect_idx--)
+ {
+ sect_cb = pSect->sect_cb;
+ sect_end = pSect->sect_end;
+ pSect++;
+
+ CALL pv_memset(
+ &pHuffBookUsed[sect_start],
+ sect_cb,
+ (sect_end - sect_start));
+
+ }
+ ENDFOR
+
+ fac = global_gain;
+ is_pos = 0;
+ noise_nrg = global_gain - NOISE_OFFSET;
+
+ pTable = pBook[BOOKSCL].pTable;
+ group_win = 0;
+ group_end = 0;
+
+ WHILE((group_end < pFrameInfo->num_win)&&(status == SUCCESS))
+ {
+ nsfb_win = pFrameInfo->sfb_per_win[group_end];
+ group_end = *pGroup++;
+
+ FOR(sfb = 0; sfb < nsfb_win; sfb++)
+ {
+ IF ((pHuffBookUsed[sfb] > 0)&&(pHuffBookUsed[sfb] < BOOKSCL))
+ {
+ cw_index = CALL decode_huff_cw_binary(pTable, pInputStream);
+
+ fac += cw_index - MIDFAC;
+
+ IF((fac >= 2*TEXP) || (fac < 0))
+ {
+ status = 1;
+ }
+ ELSE
+ {
+ pFactors[sfb] = fac;
+ }
+ ENDIF (fac)
+
+ }
+ ELSE IF (pHuffBookUsed[sfb] == ZERO_HCB)
+ {
+ do nothing;
+ }
+
+ ELSE IF ((pHuffBookUsed[sfb] == INTENSITY_HCB)||
+ (pHuffBookUsed[sfb] == INTENSITY_HCB2))
+ {
+ cw_index = CALL decode_huff_cw_binary(pTable, pInputStream);
+
+ is_pos += cw_index - MIDFAC;
+ pFactors[sfb] = is_pos;
+ }
+
+ ELSE IF (pHuffBookUsed[sfb] == NOISE_HCB)
+ {
+ IF (noise_pcm_flag == TRUE)
+ {
+ noise_pcm_flag = FALSE;
+ dpcm_noise_nrg = CALL getbits(
+ NOISE_PCM_BITS,
+ pInputStream);
+
+ dpcm_noise_nrg -= NOISE_PCM_OFFSET;
+ }
+ ELSE
+ {
+ dpcm_noise_nrg = CALL decode_huff_cw_binary(
+ pTable,
+ pInputStream);
+
+ dpcm_noise_nrg -= MIDFAC;
+ }
+ ENDIF (noise_pcm_flag)
+
+ noise_nrg += dpcm_noise_nrg;
+ pFactors[sfb] = noise_nrg;
+ }
+
+ ELSE IF (pHuffBookUsed[sfb] == BOOKSCL)
+ {
+ status = 1;
+ }
+ ENDIF (pHuffBookUsed[sfb])
+
+ }
+ ENDFOR (sfb)
+
+ IF (pFrameInfo->islong == FALSE)
+ {
+
+ FOR(group_win++; group_win < group_end; group_win++)
+ {
+ FOR (sfb=0; sfb < nsfb_win; sfb++)
+ {
+ pFactors[sfb + nsfb_win] = pFactors[sfb];
+ }
+ ENDFOR
+
+ pFactors += nsfb_win;
+ }
+ ENDFOR
+
+ }
+ ENDIF (pFrameInfo)
+
+ pHuffBookUsed += nsfb_win;
+ pFactors += nsfb_win;
+
+ }
+ ENDWHILE (group_end)
+
+ return status;
+
+------------------------------------------------------------------------------
+ RESOURCES USED
+ When the code is written for a specific target processor the
+ the resources used should be documented below.
+
+ STACK USAGE: [stack count for this module] + [variable to represent
+ stack usage for each subroutine called]
+
+ where: [stack usage variable] = stack usage for [subroutine
+ name] (see [filename].ext)
+
+ DATA MEMORY USED: x words
+
+ PROGRAM MEMORY USED: x words
+
+ CLOCK CYCLES: [cycle count equation for this module] + [variable
+ used to represent cycle count for each subroutine
+ called]
+
+ where: [cycle count variable] = cycle count for [subroutine
+ name] (see [filename].ext)
+
+------------------------------------------------------------------------------
+*/
+
+
+/*----------------------------------------------------------------------------
+; INCLUDES
+----------------------------------------------------------------------------*/
+#include "pv_audio_type_defs.h"
+#include "aac_mem_funcs.h" /* pv_memset */
+#include "s_frameinfo.h"
+#include "s_bits.h"
+#include "s_sectinfo.h"
+#include "s_huffman.h"
+#include "ibstream.h"
+
+#include "hcbtables.h"
+#include "e_huffmanconst.h"
+#include "e_infoinitconst.h"
+#include "huffman.h"
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+Int hufffac(
+ FrameInfo *pFrameInfo,
+ BITS *pInputStream,
+ Int *pGroup, /* may be changed to Int */
+ Int nsect,
+ SectInfo *pSect, /* may be changed to Int */
+ Int global_gain,
+ Int *pFactors,
+ Int huffBookUsed[])
+{
+ Int sect_idx;
+ Int group_end; /* index of 1st window in next group */
+ Int group_win; /* window index within group */
+ Int cw_index; /* huff codeword index */
+ Int nsfb_win; /* # of scfbands per window */
+ Int sfb; /* scalefactor band index */
+ Int sect_cb; /* huff codebook # for each section */
+ Int fac; /* decoded scf */
+ Int is_pos; /* intensity stereo position */
+ Int noise_pcm_flag = TRUE; /* first PNS sfb */
+ Int dpcm_noise_nrg; /* dpcm noise energy */
+ Int noise_nrg; /* noise energy */
+ Int status = SUCCESS; /* status of decoding */
+ Int *pHuffBookUsed = &huffBookUsed[0];
+
+
+ pv_memset(pFactors,
+ ZERO_HCB,
+ MAXBANDS*sizeof(*pFactors));
+
+
+ if (nsect)
+ {
+ /* read section length and codebook */
+
+ if (nsect == 1) /* long window */
+ {
+ sect_cb = pSect->sect_cb; /* codebook for this section */
+
+ /* all sfbs in one section share the same codebook */
+
+ for (sfb = pSect->sect_end >> 2; sfb != 0; sfb--)
+ {
+ *(pHuffBookUsed++) = sect_cb;
+ *(pHuffBookUsed++) = sect_cb;
+ *(pHuffBookUsed++) = sect_cb;
+ *(pHuffBookUsed++) = sect_cb;
+ }
+ for (sfb = pSect->sect_end & 3; sfb != 0; sfb--)
+ {
+ *(pHuffBookUsed++) = sect_cb;
+ }
+
+ }
+ else /* short */
+ {
+ Int sect_start = 0; /* start index of sfb for each section */
+ for (sect_idx = nsect; sect_idx > 0; sect_idx--)
+ {
+ sect_cb = pSect->sect_cb; /* codebook for this section */
+
+ /* all sfbs in one section share the same codebook */
+ for (sfb = sect_start; sfb < pSect->sect_end; sfb++)
+ {
+ pHuffBookUsed[sfb] = sect_cb;
+ }
+
+ pSect++;
+ sect_start = sfb;
+
+ } /* for (sect_idx) */
+ }
+ }
+ else
+ {
+ /* clear array for the case of max_sfb == 0 */
+ pv_memset(pHuffBookUsed,
+ ZERO_HCB,
+ MAXBANDS*sizeof(*pHuffBookUsed));
+ }
+
+ pHuffBookUsed = &huffBookUsed[0];
+
+ /* scale factors and noise energy are dpcm relative to global gain
+ * intensity positions are dpcm relative to zero
+ */
+ fac = global_gain;
+ is_pos = 0;
+ noise_nrg = global_gain - NOISE_OFFSET;
+
+ /* get scale factors,
+ * use reserved Table entry = 12, see reference (2) p78 Table 4.6.2
+ */
+ group_win = 0;
+ group_end = 0;
+
+
+ /* group by group decoding scalefactors and/or noise energy
+ * and/or intensity position
+ */
+ while ((group_end < pFrameInfo->num_win) && (status == SUCCESS))
+ {
+ nsfb_win = pFrameInfo->sfb_per_win[group_end];
+ group_end = *pGroup++; /* index of 1st window in next group */
+
+ /* decode scf in first window of each group */
+
+ for (sfb = 0; sfb < nsfb_win; sfb++)
+ {
+
+ switch (pHuffBookUsed[sfb])
+ {
+ case ZERO_HCB:
+ break;
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ /* intensity books */
+ /* decode intensity position */
+ cw_index = decode_huff_scl(pInputStream);
+
+ is_pos += cw_index - MIDFAC;
+ pFactors[sfb] = is_pos;
+ break;
+ case NOISE_HCB:
+ /* noise books */
+ /* decode noise energy */
+ if (noise_pcm_flag == TRUE)
+ {
+ noise_pcm_flag = FALSE;
+ dpcm_noise_nrg = get9_n_lessbits(NOISE_PCM_BITS,
+ pInputStream);
+
+ dpcm_noise_nrg -= NOISE_PCM_OFFSET;
+ }
+ else
+ {
+ dpcm_noise_nrg = decode_huff_scl(pInputStream);
+
+ dpcm_noise_nrg -= MIDFAC;
+ } /* if (noise_pcm_flag) */
+
+ noise_nrg += dpcm_noise_nrg;
+ pFactors[sfb] = noise_nrg;
+ break;
+ case BOOKSCL:
+ status = 1; /* invalid books */
+ sfb = nsfb_win; /* force out */
+ break;
+ default:
+ /* spectral books */
+ /* decode scale factors */
+ cw_index = decode_huff_scl(pInputStream);
+
+ fac += cw_index - MIDFAC; /* 1.5 dB */
+ if ((fac >= 2*TEXP) || (fac < 0))
+ {
+ status = 1; /* error, MUST 0<=scf<256, Ref. p73 */
+ }
+ else
+ {
+ pFactors[sfb] = fac; /* store scf */
+ } /* if (fac) */
+ }
+
+ } /* for (sfb=0), first window decode ends */
+
+ /* expand scf to other windows in the same group */
+ if (pFrameInfo->islong == FALSE)
+ {
+
+ for (group_win++; group_win < group_end; group_win++)
+ {
+ for (sfb = 0; sfb < nsfb_win; sfb++)
+ {
+ pFactors[sfb + nsfb_win] = pFactors[sfb];
+ }
+ pFactors += nsfb_win;
+ }
+
+ } /* if (pFrameInfo->islong), one group decode ends */
+
+
+ /* points to next group */
+ pHuffBookUsed += nsfb_win;
+ pFactors += nsfb_win;
+
+ } /* while (group_end), all groups decode end */
+
+ return status;
+
+} /* hufffac */
+