From dacaa73ae5010b66f4224d70a520945e5b653544 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 7 Dec 2009 09:56:32 -0800 Subject: Initial check in of stagefright software AAC decoder based on PV source code. --- media/libstagefright/codecs/aacdec/unpack_idx.cpp | 660 ++++++++++++++++++++++ 1 file changed, 660 insertions(+) create mode 100644 media/libstagefright/codecs/aacdec/unpack_idx.cpp (limited to 'media/libstagefright/codecs/aacdec/unpack_idx.cpp') 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 */ -- cgit v1.1