summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/aacdec/unpack_idx.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2009-12-07 09:56:32 -0800
committerAndreas Huber <andih@google.com>2009-12-07 11:02:28 -0800
commitdacaa73ae5010b66f4224d70a520945e5b653544 (patch)
treea2c9e71b6337dd25d149bd5fa43f7a782e9387fb /media/libstagefright/codecs/aacdec/unpack_idx.cpp
parent5921fb51e0219ddd7cad439a73495f320c57d50e (diff)
downloadframeworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.zip
frameworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.tar.gz
frameworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.tar.bz2
Initial check in of stagefright software AAC decoder based on PV source code.
Diffstat (limited to 'media/libstagefright/codecs/aacdec/unpack_idx.cpp')
-rw-r--r--media/libstagefright/codecs/aacdec/unpack_idx.cpp660
1 files changed, 660 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/unpack_idx.cpp b/media/libstagefright/codecs/aacdec/unpack_idx.cpp
new file mode 100644
index 0000000..9180994
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/unpack_idx.cpp
@@ -0,0 +1,660 @@
+/* ------------------------------------------------------------------
+ * 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/unpack_idx.c
+ Function: unpack_idx
+ unpack_idx_sgn
+ unpack_idx_esc
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Modified from original shareware code
+
+ Description: Eliminated 3 divisions and 1 multiplication through a table
+ look-up method for calculating 1/mod and constant allocation of 1/mod^3
+ and 1/mod^2.
+ Eliminated 3 additions through simple optimizations in the code.
+ Changed if/else statement to a switch/case utilizing fall-through.
+
+ Description: Made changes per review comments. Main improvements were
+ in change of switch/case to if statement, and use of temporary variable
+ to hold value of *pQuantSpec.
+
+ Description: (1) Typecast codeword_indx to Int32 before multiplication, this
+ assures the shift operation happens on a 32-bit product on
+ TI-C55x processor.
+ (2) define temp_spec as Int32 to avoid overflow
+
+ Description: Modified per review comments
+ (1) remove the two typecastings of codeword_indx when
+ pHuffCodebook->dim == DIMENSION_4
+ (2) temp_spec is Int because the result never exceeds 16 bits
+
+ Description: Break up and combine unpack index with sign bit reading and for
+ special escape code. Parent function must know which one of the
+ 3 functions should be called.
+
+ Description: Put back if-statement to get the max.
+
+ Description: When searching for the max, there was some instances where the
+ max was compared against a negative number, so the max was never
+ updated (defaulted to 0), leading to block processing in other
+ magnitude sensitive stages.
+
+ Who: Date:
+ Description:
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ Int quant_spec[] = Array for storage of the quantized
+ spectral coefficients. Length is either 2 or 4.
+ See Ref #1, Page 76 for a complete description.
+
+ Int codeword_indx = The index into the Huffman table.
+ Range is [1-288]
+
+ const Hcb *pHuffCodebook = Pointer to HuffmanCodebook information.
+
+ BITS *pInputStream = Pointer to the bitstream buffer.
+ Int *max = Pointer to maximum coefficient value.
+
+ Local Stores/Buffers/Pointers Needed:
+ const UInt div_mod[18] = An array with the values for 1/mod
+ stored in Q-formats 13.
+
+ Global Stores/Buffers/Pointers Needed:
+ None
+
+ Outputs:
+ None
+
+ Pointers and Buffers Modified:
+ Int quant_spec[] = Output (the quantized and signed spectral coefficients)
+ returned via this pointer.
+
+ Local Stores Modified:
+ None
+
+ Global Stores Modified:
+ None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function decodes quantized spectral coefficients and decode their signs
+ from the input bitstream. Quantized spectral coefficients are transmitted as
+ four-tuples or 2-tuples, and this information is conveyed to the function via
+ the variable HuffCodebook->dim.
+
+ See Reference #1 for a complete description
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ This function shall correctly calculate pQuantSpec[], given the inputs
+
+ codeword_indx = {1-288};
+ HuffCodebook->off = {0, 1, 4};
+ HuffCodebook->mod = {3, 8, 9, 13, 17};
+
+ mod = LAV + 1 if unsigned codebook
+ mod = 2*LAV + 1 if signed codebook
+
+ Range of values for LAV is {2,7,12,16} if unsigned
+ {1,4} if signed
+
+ Additionally,
+ LAV <= 2 if dim == 4
+
+ This restricts mod == 3 if dim == 4
+ and mod == {3, 8, 9, 13, 17} if dim == 2
+
+ This function will NOT function correctly if fed values that do not
+ meet the requirements as stated above.
+
+ This limitation on the range of values was determined by analysis
+ of Reference #1 (see below.)
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ (1) ISO/IEC 14496-3:1999(E)
+ Part 3
+ Subpart 4.6.3.3 Decoding Process
+ Subpart 4.6.4 Tables
+ (2) 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.
+
+------------------------------------------------------------------------------
+ PSEUDO-CODE
+
+ IF (pHuffCodebook->dim == 4)
+ *(pQuantSpec) = codeword_indx/(3^3);
+ codeword_indx = codeword_indx - *(pQuantSpec)*(3^3);
+ *(pQuantSpec) = *(pQuantSpec) - off;
+
+ pQuantSpec = pQuantSpec + 1;
+
+ *(pQuantSpec) = codeword_indx/(3^2);
+ codeword_indx = codeword_indx - *(pQuantSpec)*(3^2);
+ *(pQuantSpec) = *(pQuantSpec) - off;
+
+ pQuantSpec = pQuantSpec + 1;
+ ENDIF
+
+ *(pQuantSpec) = codeword_indx/mod;
+ codeword_indx = codeword_indx - (*pQuantSpec)*mod;
+ *(pQuantSpec) = *(pQuantSpec) - off;
+
+ pQuantSpec = pQuantSpec + 1;
+
+ *(pQuantSpec) = codeword_indx - off;
+
+------------------------------------------------------------------------------
+ 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 "s_hcb.h"
+#include "ibstream.h"
+#include "unpack_idx.h"
+
+#include "fxp_mul32.h"
+
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+#define DIV_3_CUBED 19 /* 19 = 1/27 in Q-9 format */
+#define THREE_CUBED 27 /* 27 = 3^3 */
+
+#define DIV_3_SQUARED 57 /* 57 = 1/9 in Q-9 format */
+#define THREE_SQUARED 9 /* 9 = 3^2 */
+
+#define Q_FORMAT_MOD 13 /* Q-format for 1/mod table */
+#define Q_FORMAT_MOD2 9 /* Q-format for DIV_3_SQUARED */
+#define Q_FORMAT_MOD3 9 /* Q-format for DIV_3_CUBED */
+
+#define LOWER_5_BITS_MASK 0x1F
+
+
+#if ( defined(PV_ARM_V5) || defined(PV_ARM_V4))
+
+__inline Int32 abs1(Int32 x)
+{
+ Int32 z;
+ /*
+ z = x - (x<0);
+ x = z ^ sign(z)
+ */
+ __asm
+ {
+ sub z, x, x, lsr #31
+ eor x, z, z, asr #31
+ }
+ return (x);
+}
+
+#define pv_abs(x) abs1(x)
+
+
+#else
+
+#define pv_abs(x) ((x) > 0)? (x) : (-x)
+
+#endif
+
+
+
+/*----------------------------------------------------------------------------
+; LOCAL FUNCTION DEFINITIONS
+; Function Prototype declaration
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; LOCAL STORE/BUFFER/POINTER DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------
+ Possible values for mod = {3,8,9,13,17}
+
+ There exists "empty" spaces in the table. These can potentially
+ be utilized by other const tables, if available memory becomes an issue.
+---------------------------------------------------------------------------*/
+
+const Int div_mod[18] = /* mod index Q-format */
+{
+ /* ----------------------- */
+ 0xCC, /* | | 0 | */
+ 0xCC, /* | | 1 | */
+ 0xCC, /* | | 2 | */
+ 2731, /* | 3 | 3 | 13 */
+ 0xCC, /* | | 4 | */
+ 0xCC, /* | | 5 | */
+ 0xCC, /* | | 6 | */
+ 0xCC, /* | | 7 | */
+ 1025, /* | 8 | 8 | 13 */
+ 911, /* | 9 | 9 | 13 */
+ 0xCC, /* | | 10 | */
+ 0xCC, /* | | 11 | */
+ 0xCC, /* | | 12 | */
+ 631, /* | 13 | 13 | 13 */
+ 0xCC, /* | | 14 | */
+ 0xCC, /* | | 15 | */
+ 0xCC, /* | | 16 | */
+ 482, /* | 17 | 17 | 13 */
+};
+
+/*----------------------------------------------------------------------------
+; 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
+----------------------------------------------------------------------------*/
+void unpack_idx(
+ Int16 quant_spec[],
+ Int codeword_indx,
+ const Hcb *pHuffCodebook,
+ BITS *pInputStream,
+ Int *max)
+{
+ Int16 *pQuantSpec = &quant_spec[0];
+ Int temp_spec;
+
+ const Int mod = pHuffCodebook->mod;
+ const Int off = pHuffCodebook->off;
+
+ OSCL_UNUSED_ARG(pInputStream);
+
+
+ if (pHuffCodebook->dim == DIMENSION_4)
+ {
+ /* Calculate pQuantSpec[0] */
+
+ temp_spec = (codeword_indx * DIV_3_CUBED) >> Q_FORMAT_MOD3;
+
+ codeword_indx -= temp_spec * THREE_CUBED;
+
+ temp_spec -= off;
+ *pQuantSpec++ = (Int16)temp_spec;
+
+ temp_spec = pv_abs(temp_spec);
+
+ if (temp_spec > *max)
+ {
+ *max = temp_spec;
+ }
+
+ /* Calculate pQuantSpec[1] */
+ temp_spec = (codeword_indx * DIV_3_SQUARED) >> Q_FORMAT_MOD2;
+
+ codeword_indx -= temp_spec * THREE_SQUARED;
+
+ temp_spec -= off;
+ *pQuantSpec++ = (Int16)temp_spec;
+
+ temp_spec = pv_abs(temp_spec);
+
+ if (temp_spec > *max)
+ {
+ *max = temp_spec;
+ }
+ }
+
+ /*
+ * Calculate pQuantSpec[2] if dim == 4
+ * Calculate pQuantSpec[0] if dim == 2
+ */
+
+ temp_spec = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD;
+
+ codeword_indx -= temp_spec * mod;
+
+ temp_spec -= off;
+ *pQuantSpec++ = (Int16)temp_spec;
+
+ temp_spec = pv_abs(temp_spec);
+
+
+ if (temp_spec > *max)
+ {
+ *max = temp_spec;
+ }
+
+ /*
+ * Calculate pQuantSpec[3] if dim == 4
+ * Calculate pQuantSpec[1] if dim == 2
+ */
+ codeword_indx -= off;
+ *pQuantSpec = (Int16)codeword_indx ;
+
+
+ codeword_indx = pv_abs(codeword_indx);
+
+ if (codeword_indx > *max)
+ {
+ *max = codeword_indx;
+ }
+
+
+ return ;
+} /* unpack_idx */
+
+
+void unpack_idx_sgn(
+ Int16 quant_spec[],
+ Int codeword_indx,
+ const Hcb *pHuffCodebook,
+ BITS *pInputStream,
+ Int *max)
+{
+ Int16 *pQuantSpec = &quant_spec[0];
+ Int temp_spec;
+ Int sgn;
+
+ const Int mod = pHuffCodebook->mod;
+ const Int off = pHuffCodebook->off;
+
+
+
+ if (pHuffCodebook->dim == DIMENSION_4)
+ {
+ /* Calculate pQuantSpec[0] */
+ preload_cache((Int32 *)pQuantSpec);
+ temp_spec = (codeword_indx * DIV_3_CUBED) >> Q_FORMAT_MOD3;
+
+ codeword_indx -= temp_spec * THREE_CUBED;
+
+ temp_spec -= off;
+ if (temp_spec)
+ {
+ sgn = get1bits(pInputStream);
+
+
+ *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec);
+
+ temp_spec = pv_abs(temp_spec);
+
+ if (temp_spec > *max)
+ {
+ *max = temp_spec;
+ }
+
+ }
+ else
+ {
+ *pQuantSpec++ = 0;
+ }
+
+ /* Calculate pQuantSpec[1] */
+ temp_spec = (codeword_indx * DIV_3_SQUARED) >> Q_FORMAT_MOD2;
+
+ codeword_indx -= temp_spec * THREE_SQUARED;
+
+ temp_spec -= off;
+ if (temp_spec)
+ {
+
+ sgn = get1bits(pInputStream);
+
+ *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec);
+
+ temp_spec = pv_abs(temp_spec);
+
+ if (temp_spec > *max)
+ {
+ *max = temp_spec;
+ }
+ }
+ else
+ {
+ *pQuantSpec++ = 0;
+ }
+ }
+
+ /*
+ * Calculate pQuantSpec[2] if dim == 4
+ * Calculate pQuantSpec[0] if dim == 2
+ */
+
+ temp_spec = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD;
+
+ codeword_indx -= temp_spec * mod;
+
+ temp_spec -= off;
+ if (temp_spec)
+ {
+
+ sgn = get1bits(pInputStream);
+
+ *pQuantSpec++ = (Int16)((sgn) ? -temp_spec : temp_spec);
+
+ temp_spec = pv_abs(temp_spec);
+
+ if (temp_spec > *max)
+ {
+ *max = temp_spec;
+ }
+ }
+ else
+ {
+ *pQuantSpec++ = 0;
+ }
+
+ /*
+ * Calculate pQuantSpec[3] if dim == 4
+ * Calculate pQuantSpec[1] if dim == 2
+ */
+ codeword_indx -= off;
+ if (codeword_indx)
+ {
+
+ sgn = get1bits(pInputStream);
+
+ *pQuantSpec = (Int16)((sgn) ? -codeword_indx : codeword_indx);
+
+ codeword_indx = pv_abs(codeword_indx);
+
+ if (codeword_indx > *max)
+ {
+ *max = codeword_indx;
+ }
+ }
+ else
+ {
+ *pQuantSpec = 0;
+ }
+
+ return ;
+} /* unpack_idx_sgn */
+
+
+void unpack_idx_esc(
+ Int16 quant_spec[],
+ Int codeword_indx,
+ const Hcb *pHuffCodebook,
+ BITS *pInputStream,
+ Int *max)
+{
+ Int temp_spec;
+ Int sgn1 = 0, sgn2 = 0;
+ Int N;
+ Int32 esc_seq;
+
+ const Int mod = pHuffCodebook->mod;
+ const Int off = pHuffCodebook->off;
+
+
+ temp_spec = ((Int32) codeword_indx * div_mod[mod]) >> Q_FORMAT_MOD;
+
+ codeword_indx -= temp_spec * mod;
+
+ temp_spec -= off;
+ if (temp_spec)
+ {
+ sgn1 = get1bits(pInputStream);
+ }
+
+ codeword_indx -= off;
+ if (codeword_indx)
+ {
+ sgn2 = get1bits(pInputStream);
+ }
+
+
+ if ((temp_spec & LOWER_5_BITS_MASK) == 16)
+ {
+ N = 3;
+ do
+ {
+ N++;
+
+ esc_seq = get1bits(pInputStream);
+
+ }
+ while (esc_seq != 0);
+
+ esc_seq = getbits(N, pInputStream);
+
+ esc_seq += (1 << N);
+
+
+ temp_spec = (Int)((temp_spec * esc_seq) >> 4);
+
+ }
+
+
+ if (sgn1)
+ {
+ quant_spec[0] = (Int16)(-temp_spec);
+ }
+ else
+ {
+ quant_spec[0] = (Int16)temp_spec;
+ }
+
+ temp_spec = pv_abs(temp_spec);
+
+ if (temp_spec > *max)
+ {
+ *max = temp_spec;
+ }
+
+ if ((codeword_indx & LOWER_5_BITS_MASK) == 16)
+ {
+ N = 3;
+ do
+ {
+ N++;
+
+ esc_seq = get1bits(pInputStream);
+
+ }
+ while (esc_seq != 0);
+
+ esc_seq = getbits(N, pInputStream);
+
+ esc_seq += (1 << N);
+
+ codeword_indx = (Int)((codeword_indx * esc_seq) >> 4);
+ }
+
+
+
+
+ if (sgn2)
+ {
+ quant_spec[1] = (Int16)(-codeword_indx);
+ }
+ else
+ {
+ quant_spec[1] = (Int16)codeword_indx;
+ }
+
+
+ codeword_indx = pv_abs(codeword_indx);
+
+ if (codeword_indx > *max)
+ {
+ *max = codeword_indx;
+ }
+
+
+ return ;
+} /* unpack_idx_esc */