summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/aacdec/get_ics_info.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/aacdec/get_ics_info.cpp')
-rw-r--r--media/libstagefright/codecs/aacdec/get_ics_info.cpp608
1 files changed, 608 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/get_ics_info.cpp b/media/libstagefright/codecs/aacdec/get_ics_info.cpp
new file mode 100644
index 0000000..17204cc
--- /dev/null
+++ b/media/libstagefright/codecs/aacdec/get_ics_info.cpp
@@ -0,0 +1,608 @@
+/* ------------------------------------------------------------------
+ * 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/get_ics_info.c
+
+------------------------------------------------------------------------------
+ REVISION HISTORY
+
+ Description: Modified from original shareware code
+
+ Description: Modified to pass variables by reference to eliminate use
+ of global variables.
+
+ Description: Clean up code.
+
+ Description: Fix comments before review, remove lpflag[]
+
+ Description: Update per review comments, and match ISO/IEC 14496-3
+
+ Description: Update per peer review comments.
+
+ Description: Remove "rollback" of used bits, since lt_decode is to change.
+
+ 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:
+ audioObjectType = MP4 Audio Object Type for the current song. Only if
+ this is set to LTP (MP4AUDIO_LTP) will long term
+ prediction bits be retrieved. Data type
+ tMP4AudioObjectType, which is an enumeration, which in
+ turn is an Int.
+
+ pInputStream = pointer to a BITS structure, used by the function getbits
+ to provide data. This is the second parameter to this
+ function to match its position in getbits().
+ Data type pointer to BITS structure
+
+ common_window = field read in huffdecode, which tells whether information
+ is shared between the left and right channel. Long term
+ prediction (LTP) data is NOT shared even if its a common
+ window, so this flag is needed to see if another set of
+ LTP possibly needs to be read. If this flag is false,
+ pSecondLTPStatus is not touched, it could be NULL if
+ need be. Data type Bool, which is Int.
+
+ pWindowSequence = pointer to where the the window type of the current
+ frame and channel should be placed, of data type
+ WINDOW_SEQUENCE, which is Int. It can take on one
+ of four values: ONLY_LONG_SEQUENCE, LONG_START_SEQUENCE,
+ EIGHT_SHORT_SEQUENCE, LONG_STOP_SEQUENCE,
+
+ pWindowShape = pointer to where the window shape for the current frame
+ and channel should be placed, of data type WINDOW_SHAPE,
+ which is Int. It can take on the one of these two values:
+ SINE_WINDOW, KAISER_BESSEL_WINDOW. It is used in the
+ "filterbank" section of decoding.
+
+ group = array that holds the index of the first window in each
+ group. Data type array of Int, eight elements.
+
+ p_max_sfb = pointer to where the maximum number of scale factor bands
+ for the current frame and channel will be placed. Data
+ type of pointer to Int.
+
+ p_winmap = array of pointers to all of the possible four window
+ configurations. This parameter did not need to be pointers,
+ and could be changed in the future. Data type array of pointers
+ to FrameInfo structures, length 4.
+
+ pFirstLTPStatus = pointer to a structure where the first LTP
+ information will be stored. It would be confusing and wrong
+ to call this left LTP status since if common_window = FALSE,
+ this function will be called twice - once for the left, once
+ for the right. It could be done, but extra conditional code
+ would need to be done.
+ Data type pointer to LT_PRED_STATUS structure.
+
+ pSecondLTPStatus = pointer to where the right channel of LTP
+ information will be stored only if common_window is non-zero.
+ Data type pointer to LT_PRED_STATUS structure.
+
+ Local Stores/Buffers/Pointers Needed: None.
+
+ Global Stores/Buffers/Pointers Needed: None.
+
+ Outputs:
+ status = 0 implies no error occurred, non-zero otherwise.
+
+ Pointers and Buffers Modified:
+ pInputStream contents are modified in such a way that the number of bits
+ read increases.
+ pWindowSequence contents are updated with the current window for this
+ frame and channel
+ group[] contents will be modified to grouping information. See getgroup
+ source code for a better description of what this is.
+ p_max_sfb contents will be updated with the maximum scale factor bands
+ for this frame and channel.
+ pFirstLTPStatus contents may be updated if the stream has long term
+ prediction information.
+ pSecondLTPStatus contents may be updated if common_window != 0 and LTP data
+ is present.
+
+
+ Local Stores Modified: None
+
+ Global Stores Modified: None
+
+------------------------------------------------------------------------------
+ FUNCTION DESCRIPTION
+
+ This function retrieves the individual channel stream (ICS) information
+ from the bitstream. The information read for the current
+ frame and channel is:
+ - window sequence
+ - window shape for use in the filter bank
+ - number of scale factor bands
+ - long term predication (LTP) information
+ - grouping information
+
+ This function does NOT support MPEG2 style AAC Frequency Domain Predictor,
+ not to be confused with LTP (Long Term Prediction). If such data is found
+ to be on the file an error is generated.
+
+------------------------------------------------------------------------------
+ REQUIREMENTS
+
+ This function is not to use static or global data.
+
+------------------------------------------------------------------------------
+ REFERENCES
+
+ (1) ISO/IEC 14496-3:1999(E) Titled "Information technology - Coding
+ of audio-visual objects Part 3: Audio Subpart 4:"
+ Table 4.4.6 - Syntax of ics_info(), page 16.
+
+
+ (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 = 0;
+ first_ltp_data_present = FALSE;
+ second_ltp_data_present = FALSE;
+
+
+ CALL getbits(
+ neededBits = LEN_ICS_RESERV + LEN_WIN_SEQ + LEN_WIN_SH,
+ pInputStream = pInputStream)
+ MODIFYING( pInputStream )
+ RETURNING( temp = returnValue )
+
+ windowSequence = (temp >> LEN_WIN_SH) & ((0x1<<LEN_WIN_SEQ)-1);
+
+ *pWindowShape = (temp) & ((0x1<<LEN_WIN_SH)-1);
+
+ IF (windowSequence == EIGHT_SHORT_SEQUENCE)
+ THEN
+ CALL getbits(
+ neededBits = LEN_MAX_SFBS,
+ pInputStream = pInputStream)
+ MODIFYING(pInputStream)
+ RETURNING(local_max_sfb = returnValue)
+
+ CALL getgroup(
+ group = group,
+ pInputStream = pInputStream)
+ MODIFYING(group)
+ MODIFYING(pInputStream)
+ RETURNING(nothing)
+
+
+ ELSE
+
+ group[0] = 1;
+
+ CALL getbits(
+ neededBits = LEN_MAX_SFBL + LEN_PREDICTOR_DATA_PRESENT,
+ pInputStream = pInputStream)
+ MODIFYING(pInputStream)
+ RETURNING(temp = returnValue)
+
+ predictor_data_present =
+ (Bool) getbits(
+ LEN_BOOLEAN,
+ pInputStream);
+
+ local_max_sfb = (Int)(temp >> LEN_PREDICTOR_DATA_PRESENT);
+
+ predictor_data_present =
+ (Bool) (temp & ((0x1 << LEN_PREDICTOR_DATA_PRESENT)-1));
+
+ IF (local_max_sfb > allowed_max_sfb)
+ THEN
+ status = 1
+ ELSEIF (audioObjectType == MP4AUDIO_LTP)
+ THEN
+ IF (predictor_data_present != FALSE)
+ THEN
+ CALL getbits(
+ neededBits = LEN_LTP_DATA_PRESENT,
+ pInputStream = pInputStream)
+ MODIFYING(pInputStream)
+ RETURNING(first_ltp_data_present = returnValue)
+
+ IF (ltp_data_present != FALSE)
+ THEN
+
+ CALL lt_decode(
+ win_type = windowSequence,
+ pInputStream = pInputStream,
+ max_sfb = local_max_sfb,
+ pLt_pred = pFirstLTPStatus)
+ MODIFYING(pInputStream)
+ MODIFYING(pFirstLTPStatus)
+ RETURNING(nothing)
+
+ ENDIF
+
+ IF (common_window != FALSE)
+ THEN
+ CALL getbits(
+ neededBits = LEN_LTP_DATA_PRESENT,
+ pInputStream = pInputStream)
+ MODIFYING(pInputStream)
+ RETURNING(second_ltp_data_present = returnValue)
+
+ IF (second_ltp_data_present != FALSE)
+ THEN
+
+ CALL lt_decode(
+ win_type = windowSequence,
+ pInputStream = pInputStream,
+ max_sfb = local_max_sfb,
+ pLt_pred = pSecondLTPStatus)
+ MODIFYING(pInputStream)
+ MODIFYING(pSecondLTPStatus)
+ RETURNING(nothing)
+ ENDIF
+ ENDIF
+ ENDIF
+ ELSE
+ IF (predictor_data_present != FALSE)
+ THEN
+ status = 1
+ ENDIF
+ END IF
+ ENDIF
+
+ pFirstLTPStatus->ltp_data_present = first_ltp_data_present;
+
+ IF (common_window != FALSE)
+ THEN
+ pSecondLTPStatus->ltp_data_present = second_ltp_data_present;
+ ENDIF
+
+ pFrameInfo = p_winmap[*p_wnd];
+ IF (local_max_sfb > pFrameInfo->sfb_per_frame)
+ THEN
+ status = 1;
+ ENDIF
+
+ *(p_max_sfb) = local_max_sfb;
+
+ MODIFY(*(pWindowSequence))
+ MODIFY(*(pWinShape))
+ MODIFY(*(p_max_sfb))
+ MODIFY(group[])
+ MODIFY(*pInputStream)
+ MODIFY(*pFirstLTPStatus)
+ MODIFY(*pSecondLTPStatus)
+ 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 "e_rawbitstreamconst.h"
+#include "e_tmp4audioobjecttype.h"
+
+#include "s_bits.h"
+#include "s_frameinfo.h"
+#include "s_lt_pred_status.h"
+
+#include "ibstream.h"
+#include "lt_decode.h"
+#include "ltp_common_internal.h" /* For LEN_LTP_DATA_PRESENT constant */
+
+#include "get_ics_info.h"
+#include "huffman.h" /* For the declaration of getgroup */
+
+/*----------------------------------------------------------------------------
+; MACROS
+; Define module specific macros here
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; DEFINES
+; Include all pre-processor statements here. Include conditional
+; compile variables also.
+----------------------------------------------------------------------------*/
+
+#define LEN_PREDICTOR_DATA_PRESENT (1)
+
+/*----------------------------------------------------------------------------
+; 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
+----------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------
+; FUNCTION CODE
+----------------------------------------------------------------------------*/
+
+Int get_ics_info(
+ const tMP4AudioObjectType audioObjectType,
+ BITS *pInputStream,
+ const Bool common_window,
+ WINDOW_SEQUENCE *pWindowSequence,
+ WINDOW_SHAPE *pWindowShape,
+ Int group[],
+ Int *p_max_sfb,
+ FrameInfo *p_winmap[],
+ LT_PRED_STATUS *pFirstLTPStatus,
+ LT_PRED_STATUS *pSecondLTPStatus)
+{
+ WINDOW_SEQUENCE windowSequence;
+ UInt temp;
+ Bool predictor_data_present;
+ UInt local_max_sfb;
+ UInt allowed_max_sfb;
+ Int status = SUCCESS;
+ Bool first_ltp_data_present = FALSE;
+ Bool second_ltp_data_present = FALSE;
+
+ /*
+ * The following three calls to getbits have been replaced with one
+ * call for speed:
+ *
+ * getbits(LEN_ICS_RESERV, pInputStream);
+ * windowSequence = getbits(LEN_WIN_SEQ, pInputStream);
+ * *pWindowShape = getbits(LEN_WIN_SH, pInputStream);
+ *
+ */
+
+ temp =
+ get9_n_lessbits(
+ LEN_ICS_RESERV + LEN_WIN_SEQ + LEN_WIN_SH,
+ pInputStream);
+
+
+ windowSequence = (WINDOW_SEQUENCE)((temp >> LEN_WIN_SH) & ((0x1 << LEN_WIN_SEQ) - 1));
+
+ *pWindowShape = (WINDOW_SHAPE)((temp) & ((0x1 << LEN_WIN_SH) - 1));
+
+ /*
+ * This pointer should not be NULL as long as the initialization code
+ * has been run, so the test for NULL has been removed.
+ */
+ allowed_max_sfb = p_winmap[windowSequence]->sfb_per_win[0];
+
+ if (windowSequence == EIGHT_SHORT_SEQUENCE)
+ {
+ local_max_sfb = get9_n_lessbits(LEN_MAX_SFBS,
+ pInputStream);
+
+ getgroup(
+ group,
+ pInputStream);
+
+ if (local_max_sfb > allowed_max_sfb)
+ {
+ status = 1; /* ERROR CODE - needs to be updated */
+ }
+
+ } /* end of TRUE of if (windowSequence == EIGHT_SHORT_SEQUENCE) */
+ else
+ {
+ /* There is only one group for long windows. */
+ group[0] = 1;
+
+ /*
+ * The window is long, get the maximum scale factor bands,
+ * and get long term prediction info.
+ *
+ * Reference [1] states that the audioObjectType is first tested,
+ * then the predictor_data_present is read on either branch of the
+ * if (audioObjectType == MP4AUDIO_LTP). Instead, this code combines
+ * the two calls on both branches into one before the
+ * if, and then in turn combines with another call to getbits, all
+ * in the name of speed.
+ *
+ * This would be the individual calls, without checking the number
+ * of scale factor bands:
+ *
+ * local_max_sfb =
+ * (Int) getbits(
+ * LEN_MAX_SFBL,
+ * pInputStream);
+ *
+ * if (audioObjectType == MP4AUDIO_LTP)
+ * {
+ * predictor_data_present =
+ * (Bool) getbits(
+ * LEN_PREDICTOR_DATA_PRESENT,
+ * pInputStream);
+ *
+ * ..... (read LTP data)
+ *
+ * }
+ * else
+ * {
+ *
+ * predictor_data_present =
+ * (Bool) getbits(
+ * LEN_PREDICTOR_DATA_PRESENT,
+ * pInputStream);
+ *
+ * ..... (its an error for this library)
+ * }
+ */
+ temp =
+ get9_n_lessbits(
+ LEN_MAX_SFBL + LEN_PREDICTOR_DATA_PRESENT,
+ pInputStream);
+
+ local_max_sfb = (Int)(temp >> LEN_PREDICTOR_DATA_PRESENT);
+
+ predictor_data_present =
+ (Bool)(temp & ((0x1 << LEN_PREDICTOR_DATA_PRESENT) - 1));
+
+ if (local_max_sfb > allowed_max_sfb)
+ {
+ status = 1; /* ERROR CODE - needs to be updated */
+ }
+ else if (audioObjectType == MP4AUDIO_LTP)
+ {
+ /*
+ * Note that the predictor data bit has already been
+ * read.
+ */
+
+ /*
+ * If the object type is LTP, the predictor data is
+ * LTP. If the object type is not LTP, the predictor data
+ * is so called "frequency predictor data", which is not
+ * supported by this implementation. Refer to (1)
+ */
+ if (predictor_data_present != FALSE)
+ {
+ first_ltp_data_present =
+ (Bool) get1bits(/* LEN_LTP_DATA_PRESENT,*/
+ pInputStream);
+
+ if (first_ltp_data_present != FALSE)
+ {
+ lt_decode(
+ windowSequence,
+ pInputStream,
+ local_max_sfb,
+ pFirstLTPStatus);
+ }
+ if (common_window != FALSE)
+ {
+ second_ltp_data_present =
+ (Bool) get1bits(/* LEN_LTP_DATA_PRESENT,*/
+ pInputStream);
+
+ if (second_ltp_data_present != FALSE)
+ {
+ lt_decode(
+ windowSequence,
+ pInputStream,
+ local_max_sfb,
+ pSecondLTPStatus);
+ }
+ } /* if (common_window != FALSE) */
+
+ } /* if (predictor_data_present != FALSE) */
+
+ } /* else if (audioObjectType == MP4AUDIO_LTP) */
+ else
+ {
+ /*
+ * Note that the predictor data bit has already been
+ * read.
+ */
+
+ /*
+ * The object type is not LTP. If there is data, its
+ * frequency predictor data, not supported by this
+ * implementation.
+ */
+ if (predictor_data_present != FALSE)
+ {
+ status = 1; /* ERROR CODE UPDATE LATER */
+ } /* if (predictor_data_present != FALSE) */
+
+ } /* end of "else" clause of if (audioObjectType == MP4AUDIO_LTP) */
+
+ } /* if (windowSequence == EIGHT_SHORT_SEQUENCE) [FALSE branch] */
+
+
+ /*
+ * Save all local copies.
+ */
+ pFirstLTPStatus->ltp_data_present = first_ltp_data_present;
+ if (common_window != FALSE)
+ {
+ pSecondLTPStatus->ltp_data_present = second_ltp_data_present;
+ }
+
+ *p_max_sfb = local_max_sfb;
+
+ *pWindowSequence = windowSequence;
+
+ return (status);
+
+} /* get_ics_info */
+