summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/aacdec/get_prog_config.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
commitf44de515d3b6098a0b585865c1a0c7b20d3075a6 (patch)
tree028b1d81643bbb332464b42b50a0f79ba5359142 /media/libstagefright/codecs/aacdec/get_prog_config.cpp
parentbf697e37550d9e8376089b0b5e498613bede798c (diff)
downloadframeworks_av-f44de515d3b6098a0b585865c1a0c7b20d3075a6.zip
frameworks_av-f44de515d3b6098a0b585865c1a0c7b20d3075a6.tar.gz
frameworks_av-f44de515d3b6098a0b585865c1a0c7b20d3075a6.tar.bz2
Initial check in of stagefright software AAC decoder based on PV source code.
Diffstat (limited to 'media/libstagefright/codecs/aacdec/get_prog_config.cpp')
-rw-r--r--media/libstagefright/codecs/aacdec/get_prog_config.cpp739
1 files changed, 739 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/get_prog_config.cpp b/media/libstagefright/codecs/aacdec/get_prog_config.cpp
new file mode 100644
index 0000000..6bddd57
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/get_prog_config.cpp
@@ -0,0 +1,739 @@
+/* ------------------------------------------------------------------
+ * 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: get_prog_config.c
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Modified from original shareware code
+
+ Description: Modified to pass variables by reference to eliminate use
+ of global variables.
+
+ Description: Move functionality from get_adif_header for when to change
+ the current program configuration, add a temporary config
+ to read into, clean up code, change function prototype.
+
+ Description: Clean up
+
+ Description: Update per review comments
+
+ Description: Fix double 'could'
+
+ Description: change enter_mc_info to set_mc_info
+
+ Description: update comments
+
+ Description: Replace some instances of getbits to get9_n_lessbits
+ when the number of bits read is 9 or less and get1bits
+ when only 1 bit is read.
+
+ Who: Date:
+ Description:
+
+------------------------------------------------------------------------------
+ INPUT AND OUTPUT DEFINITIONS
+
+ Inputs:
+ pVars = pointer to the structure that holds all information for
+ this instance of the library. pVars->prog_config is directly
+ used, and pVars->mc_info, pVars->prog_config, pVars->winmap,
+ pVars->SFBWidth128 are needed indirectly for calling
+ set_mc_info. Data type pointer to tDec_Int_File structure.
+
+ pScratchPCE = pointer to a temporary ProgConfig structure to be used
+ to read in the program configuration element.
+
+ Local Stores/Buffers/Pointers Needed: None
+
+ Global Stores/Buffers/Pointers Needed: None
+
+ Outputs:
+ status = zero if no error was found, non-zero otherwise.
+
+ Pointers and Buffers Modified:
+ pVars->prog_config contents are updated with the PCE read in.
+ pVars->mc_info contents are updated with channel information.
+ pVars->winmap contents are updated with window information.
+ pVars->SFBWidth128 contents are updated with scale factor band width data.
+
+ Local Stores Modified: None
+
+ Global Stores Modified: None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function reads from the input stream to memory for a temporary
+ program configuration element (PCE). If the PCE read is the first
+ encountered it is saved. Or, if the tag of the PCE read matches the tag of
+ the first PCE encounted, it is saved as well. This is a mechanism for
+ changing the sampling rate.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ This function shall not use static or global variables.
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ (1) ISO/IEC 13818-7:1997 Titled "Information technology - Generic coding
+ of moving pictures and associated audio information - Part 7: Advanced
+ Audio Coding (AAC)", Table 6.21 - Syntax of program_config_element(),
+ page 16, and section 8.5 "Program Config Element (PCE)", page 30.
+
+ (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
+
+ status = SUCCESS;
+ pInputStream = &(pVars->inputStream);
+
+
+ CALL getbits(
+ neededBits = LEN_TAG,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( tag = returnValue )
+
+ CALL getbits(
+ neededBits = LEN_PROFILE,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( pScratchPCE->profile = returnValue )
+
+ CALL getbits(
+ neededBits = LEN_PROFILE,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( pScratchPCE->sampling_rate_idx = returnValue )
+
+ CALL getbits(
+ neededBits = LEN_NUM_ELE,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->front.num_ele = temp;
+
+ CALL getbits(
+ neededBits = LEN_NUM_ELE,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->side.num_ele = temp;
+
+ CALL getbits(
+ neededBits = LEN_NUM_ELE,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->back.num_ele = temp;
+
+ CALL getbits(
+ neededBits = LEN_NUM_LFE,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->lfe.num_ele = temp;
+
+ CALL getbits(
+ neededBits = LEN_NUM_DAT,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->data.num_ele = temp;
+
+ CALL getbits(
+ neededBits = LEN_NUM_CCE,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->coupling.num_ele = temp;
+
+ CALL getbits(
+ neededBits = LEN_MIX_PRES,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( flag = returnValue )
+
+ pScratchPCE->mono_mix.present = flag;
+
+ IF (flag != FALSE)
+ THEN
+ CALL getbits(
+ neededBits = LEN_TAG,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->mono_mix.ele_tag = temp;
+
+ ENDIF
+
+ CALL getbits(
+ neededBits = LEN_MIX_PRES,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( flag = returnValue )
+
+ pScratchPCE->stereo_mix.present = flag;
+
+ IF (flag != FALSE)
+ THEN
+
+ CALL getbits(
+ neededBits = LEN_TAG,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->stereo_mix.ele_tag = temp;
+
+ ENDIF
+
+ CALL getbits(
+ neededBits = LEN_MIX_PRES,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( flag = returnValue )
+
+ flag =
+ getbits(
+ LEN_MIX_PRES,
+ pInputStream);
+
+ pScratchPCE->matrix_mix.present = flag;
+
+ IF (flag != FALSE)
+ THEN
+ CALL getbits(
+ neededBits = LEN_MMIX_IDX,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->matrix_mix.ele_tag = temp;
+
+ CALL getbits(
+ neededBits = LEN_PSUR_ENAB,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ pScratchPCE->matrix_mix.pseudo_enab = temp;
+
+ ENDIF
+
+
+ CALL get_ele_list(
+ pElementList = &pScratchPCE->front,
+ pInputStream = pInputStream,
+ enableCPE = TRUE )
+ MODIFYING( pInputStream )
+ MODIFYING( pScratchPCE->front )
+ RETURNING( nothing )
+
+ CALL get_ele_list(
+ pElementList = &pScratchPCE->side,
+ pInputStream = pInputStream,
+ enableCPE = TRUE )
+ MODIFYING( pInputStream )
+ MODIFYING( pScratchPCE->side )
+ RETURNING( nothing )
+
+ CALL get_ele_list(
+ pElementList = &pScratchPCE->back,
+ pInputStream = pInputStream,
+ enableCPE = TRUE )
+ MODIFYING( pInputStream )
+ MODIFYING( pScratchPCE->back )
+ RETURNING( nothing )
+
+ CALL get_ele_list(
+ pElementList = &pScratchPCE->lfe,
+ pInputStream = pInputStream,
+ enableCPE = FALSE )
+ MODIFYING( pInputStream )
+ MODIFYING( pScratchPCE->lfe )
+ RETURNING( nothing )
+
+ CALL get_ele_list(
+ pElementList = &pScratchPCE->data,
+ pInputStream = pInputStream,
+ enableCPE = FALSE )
+ MODIFYING( pInputStream )
+ MODIFYING( pScratchPCE->data )
+ RETURNING( nothing )
+
+ CALL get_ele_list(
+ pElementList = &pScratchPCE->coupling,
+ pInputStream = pInputStream,
+ enableCPE = TRUE )
+ MODIFYING( pInputStream )
+ MODIFYING( pScratchPCE->coupling )
+ RETURNING( nothing )
+
+
+ CALL byte_align(
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( nothing )
+
+ CALL getbits(
+ neededBits = LEN_COMMENT_BYTES,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( numChars = returnValue )
+
+ FOR (i = numChars; i > 0; i--)
+
+ CALL getbits(
+ neededBits = LEN_COMMENT_BYTES,
+ pInputStream = pInputStream )
+ MODIFYING( pInputStream )
+ RETURNING( nothing )
+
+ ENDFOR
+
+ IF (pVars->current_program < 0)
+ THEN
+ pVars->current_program = tag;
+ ENDIF
+
+
+ IF (tag == pVars->current_program)
+ THEN
+
+ CALL pv_memcpy(
+ to = &pVars->prog_config,
+ from = pScratchPCE,
+ n = sizeof(ProgConfig))
+ MODIFYING( pVars->prog_config )
+ RETURNING( nothing )
+
+ CALL set_mc_info(
+ pMC_Info = &pVars->mc_info,
+ objectType = pVars->prog_config.profile + 1,
+ samplin_rate_idx = pVars->prog_config.sampling_rate_idx,
+ tag = pVars->prog_config.front.ele_tag[0],
+ is_cpe = pVars->prog_config.front.ele_is_cpe[0],
+ pWinSeqInfo = pVars->winmap,
+ pSfbwidth128 = pVars->SFBWidth128)
+ MODIFYING( pVars->mc_info )
+ MODIFYING( pVars->winmap )
+ MODIFYING( pVars->SFBWidth128 )
+ RETURN( status = return_value )
+
+ ENDIF
+
+ MODIFY( pVars->mc_info )
+ MODIFY( pVars->winmap )
+ MODIFY( pVars->SFBWidth128 )
+ 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 "s_bits.h"
+#include "s_elelist.h"
+#include "s_tdec_int_file.h"
+#include "s_tdec_int_chan.h"
+#include "e_progconfigconst.h"
+#include "ibstream.h"
+#include "get_ele_list.h"
+#include "aac_mem_funcs.h"
+#include "set_mc_info.h"
+#include "get_prog_config.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 VARIABLE DEFINITIONS
+; Variable declaration - defined here and used outside this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL FUNCTION REFERENCES
+; Declare functions defined elsewhere and referenced in this module
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; EXTERNAL VARIABLES REFERENCES
+; Declare variables used in this module but defined elsewhere
+----------------------------------------------------------------------------*/
+
+Int get_prog_config(
+ tDec_Int_File *pVars,
+ ProgConfig *pScratchPCE)
+{
+ Int i;
+ UInt tag;
+ Int numChars;
+ UInt temp;
+ Bool flag;
+ Int status = SUCCESS;
+ BITS *pInputStream = &(pVars->inputStream);
+
+
+ /*
+ * The tag is used at the very end to see if this PCE is
+ * the one to be used. Otherwise it does not need to be saved for the
+ * the simple configurations to be used in this version of an AAC
+ * decoder.
+ *
+ * All of the bits of this PCE must be read even if this PCE will not
+ * be used. They are read into a temporary PCE, then later it is decided
+ * whether to keep this PCE.
+ *
+ * To allow quick removal of the fields from the ProgConfig structure
+ * that will probably not be used at a later date,
+ * while still advancing the bitstream pointer,the return value of
+ * getbits is saved into a temporary variable, then transfered to
+ * the structure item.
+ */
+ tag =
+ get9_n_lessbits(
+ LEN_TAG,
+ pInputStream);
+
+ pScratchPCE->profile =
+ get9_n_lessbits(
+ LEN_PROFILE,
+ pInputStream);
+
+ pScratchPCE->sampling_rate_idx =
+ get9_n_lessbits(
+ LEN_SAMP_IDX,
+ pInputStream);
+
+ if (!pVars->adif_test && pScratchPCE->sampling_rate_idx != pVars->prog_config.sampling_rate_idx)
+ {
+ /* rewind the pointer as implicit channel configuration maybe the case */
+ pInputStream->usedBits -= (LEN_TAG + LEN_PROFILE + LEN_SAMP_IDX);
+
+ return (1); /* mismatch cannot happen */
+ }
+
+
+ /*
+ * Retrieve the number of element lists for each of
+ * front, side, back, lfe, data, and coupling.
+ *
+ * For two-channel stereo or mono, only the data in the front needs
+ * to be saved. However, ALL fields need to be skipped over in some
+ * fashion. Also, the number of elements needs to be temporarily saved
+ * to call get_ele_list(). If that function was changed to pass in
+ * the number of points to be read, the memory set aside inside the
+ * ProgConfig structure could be removed.
+ */
+
+ /*
+ * The next six function calls could be combined into one, then use
+ * shifts and masks to retrieve the individual fields.
+ */
+ temp =
+ get9_n_lessbits(
+ LEN_NUM_ELE,
+ pInputStream);
+
+ pScratchPCE->front.num_ele = temp;
+
+ /* Needed only to read in the element list. */
+ temp =
+ get9_n_lessbits(
+ LEN_NUM_ELE,
+ pInputStream);
+
+ pScratchPCE->side.num_ele = temp;
+
+ /* Needed only to read in the element list. */
+ temp =
+ get9_n_lessbits(
+ LEN_NUM_ELE,
+ pInputStream);
+
+ pScratchPCE->back.num_ele = temp;
+
+ /* Needed only to read in the element list. */
+ temp =
+ get9_n_lessbits(
+ LEN_NUM_LFE,
+ pInputStream);
+
+ pScratchPCE->lfe.num_ele = temp;
+
+ /* Needed only to read in the element list. */
+ temp =
+ get9_n_lessbits(
+ LEN_NUM_DAT,
+ pInputStream);
+ pScratchPCE->data.num_ele = temp;
+
+ /* Needed only to read in the element list. */
+ temp =
+ get9_n_lessbits(
+ LEN_NUM_CCE,
+ pInputStream);
+
+ pScratchPCE->coupling.num_ele = temp;
+
+ /*
+ * Read in mix down data.
+ *
+ * Whether these fields can be removed and have proper operation
+ * will be determined at a later date.
+ */
+
+ /* Read presence of mono_mix */
+ flag =
+ get1bits(/* LEN_MIX_PRES,*/
+ pInputStream);
+
+ pScratchPCE->mono_mix.present = flag;
+
+ if (flag != FALSE)
+ {
+ temp =
+ get9_n_lessbits(
+ LEN_TAG,
+ pInputStream);
+
+ pScratchPCE->mono_mix.ele_tag = temp;
+
+ } /* end if (flag != FALSE) */
+
+ /* Read presence of stereo mix */
+ flag =
+ get1bits(/* LEN_MIX_PRES,*/
+ pInputStream);
+
+ pScratchPCE->stereo_mix.present = flag;
+
+ if (flag != FALSE)
+ {
+ temp =
+ get9_n_lessbits(
+ LEN_TAG,
+ pInputStream);
+
+ pScratchPCE->stereo_mix.ele_tag = temp;
+
+ } /* end if (flag != FALSE) */
+
+ /* Read presence of matrix mix */
+ flag =
+ get1bits(/* LEN_MIX_PRES,*/
+ pInputStream);
+
+ pScratchPCE->matrix_mix.present = flag;
+
+ if (flag != FALSE)
+ {
+ temp =
+ get9_n_lessbits(
+ LEN_MMIX_IDX,
+ pInputStream);
+
+ pScratchPCE->matrix_mix.ele_tag = temp;
+
+ temp =
+ get1bits(/* LEN_PSUR_ENAB,*/
+ pInputStream);
+
+ pScratchPCE->matrix_mix.pseudo_enab = temp;
+
+ } /* end if (flag != FALSE) */
+
+ /*
+ * Get each of the element lists. Only the front information will be
+ * used for the PV decoder, but the usedBits field of pInputStream must
+ * be advanced appropriately.
+ *
+ * This could be optimized by advancing the bit stream for the
+ * elements that do not need to be read.
+ */
+ get_ele_list(
+ &pScratchPCE->front,
+ pInputStream,
+ TRUE);
+
+ get_ele_list(
+ &pScratchPCE->side,
+ pInputStream,
+ TRUE);
+
+ get_ele_list(
+ &pScratchPCE->back,
+ pInputStream,
+ TRUE);
+
+ get_ele_list(
+ &pScratchPCE->lfe,
+ pInputStream,
+ FALSE);
+
+ get_ele_list(
+ &pScratchPCE->data,
+ pInputStream,
+ FALSE);
+
+ get_ele_list(
+ &pScratchPCE->coupling,
+ pInputStream,
+ TRUE);
+
+ /*
+ * The standard requests a byte alignment before reading in the
+ * comment. This can be done because LEN_COMMENT_BYTES == 8.
+ */
+ byte_align(pInputStream);
+
+ numChars =
+ get9_n_lessbits(
+ LEN_COMMENT_BYTES, pInputStream);
+
+ /*
+ * Ignore the comment - it requires 65 bytes to store (or worse on DSP).
+ * If this field is restored, make sure to append a trailing '\0'
+ */
+ for (i = numChars; i > 0; i--)
+ {
+ pScratchPCE->comments[i] = (Char) get9_n_lessbits(LEN_BYTE,
+ pInputStream);
+
+ } /* end for */
+
+ if (pVars->current_program < 0)
+ {
+ /*
+ * If this is the first PCE, it becomes the current, regardless of
+ * its tag number.
+ */
+ pVars->current_program = tag;
+
+ } /* end if (pVars->current_program < 0) */
+
+
+ if (tag == (UInt)pVars->current_program)
+ {
+ /*
+ * This branch is reached under two conditions:
+ * 1) This is the first PCE found, it was selected in the above if
+ * block. In all encoders found thus far, the tag value has been
+ * zero.
+ * 2) A PCE has been sent by the encoder with a tag that matches the
+ * the first one sent. It will then be re-read. No encoder found
+ * thus far re-sends a PCE, when looking at ADIF files.
+ *
+ * Regardless, the temporary PCE will now be copied into the
+ * the one official program configuration.
+ */
+ pv_memcpy(
+ &pVars->prog_config,
+ pScratchPCE,
+ sizeof(ProgConfig));
+
+ /* enter configuration into MC_Info structure */
+ status =
+ set_mc_info(
+ &pVars->mc_info,
+ (tMP4AudioObjectType)(pVars->prog_config.profile + 1),
+ pVars->prog_config.sampling_rate_idx,
+ pVars->prog_config.front.ele_tag[0],
+ pVars->prog_config.front.ele_is_cpe[0],
+ pVars->winmap,
+ pVars->SFBWidth128);
+
+ } /* end if (tag == pVars->current_program) */
+
+ return (status);
+}
+