12228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
22228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/* -----------------------------------------------------------------------------------------------------------
32228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectSoftware License for The Fraunhofer FDK AAC Codec Library for Android
42228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
54f0d97057c5c640b25518358886f8c47da9fc052Jean-Michel Trivi� Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
62228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  All rights reserved.
72228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
82228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project 1.    INTRODUCTION
92228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
112228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is intended to be used on a wide variety of Android devices.
122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
132228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectaudio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindependent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof the MPEG specifications.
172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
182228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectPatent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmay be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectindividually for the purpose of encoding or decoding bit streams in products that are compliant with
212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthe ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectthese patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware may already be covered under those patent licenses when it is used for those licensed purposes only.
242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
252228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCommercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectare also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectapplications information and documentation.
282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project2.    COPYRIGHT LICENSE
302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
312228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectRedistribution and use in source and binary forms, with or without modification, are permitted without
322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectpayment of copyright license fees provided that you satisfy the following conditions:
332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
342228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in redistributions of the FDK AAC Codec or
352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectyour modifications thereto in source code form.
362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
372228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must retain the complete text of this software license in the documentation and/or other materials
382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprovided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
392228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou must make available free of charge copies of the complete source code of the FDK AAC Codec and your
402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectmodifications thereto to recipients of copies in binary form.
412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
422228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThe name of Fraunhofer may not be used to endorse or promote products derived from this library without
432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectprior written permission.
442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
452228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectsoftware or your modifications thereto.
472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
482228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYour modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectand the date of any change. For modified versions of the FDK AAC Codec, the term
502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project3.    NO PATENT LICENSE
542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
552228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectNO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
562228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectrespect to this software.
582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
592228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectYou may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectby appropriate patent licenses.
612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project4.    DISCLAIMER
632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
642228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectThis FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectof merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
672228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectCONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectincluding but not limited to procurement of substitute goods or services; loss of use, data, or profits,
692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projector business interruption, however caused and on any theory of liability, whether in contract, strict
702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectliability, or tort (including negligence), arising in any way out of the use of this software, even if
712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectadvised of the possibility of such damage.
722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project5.    CONTACT INFORMATION
742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
752228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectFraunhofer Institute for Integrated Circuits IIS
762228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAttention: Audio and Multimedia Departments - FDK AAC LL
772228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectAm Wolfsmantel 33
782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project91058 Erlangen, Germany
792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectwww.iis.fraunhofer.de/amm
812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectamm-info@iis.fraunhofer.de
822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project----------------------------------------------------------------------------------------------------------- */
832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*****************************  MPEG-4 AAC Decoder  **************************
852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Author(s):   Daniel Homm
872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project   Description:
882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project******************************************************************************/
902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "tpdec_lib.h"
922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#include "tp_data.h"
9347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#ifdef TP_PCE_ENABLE
9447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#include "FDK_crc.h"
9547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#endif
962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid CProgramConfig_Reset(CProgramConfig *pPce)
992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->elCounter = 0;
1012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid CProgramConfig_Init(CProgramConfig *pPce)
1042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(pPce, sizeof(CProgramConfig));
1062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef TP_PCE_ENABLE
1072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->SamplingFrequencyIndex = 0xf;
1082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
1092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint  CProgramConfig_IsValid ( const CProgramConfig *pPce )
1122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
1132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return ( (pPce->isValid) ? 1 : 0);
1142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
1152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef TP_PCE_ENABLE
11747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi#define PCE_HEIGHT_EXT_SYNC  ( 0xAC )
11847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
11947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi/*
12047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * Read the extension for height info.
12147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * return 0 if successfull or -1 if the CRC failed.
12247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi */
12347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic
12447c680c62246594107da0a8995c953dfb8040bceJean-Michel Triviint CProgramConfig_ReadHeightExt(
12547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                                  CProgramConfig *pPce,
12647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                                  HANDLE_FDK_BITSTREAM bs,
12747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                                  int * const bytesAvailable,
12847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                                  const UINT alignmentAnchor
12947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                                )
13047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi{
13147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  int err = 0;
13247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  FDK_CRCINFO crcInfo;    /* CRC state info */
13347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  INT crcReg;
13447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
13547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  crcReg = FDKcrcStartReg(&crcInfo, bs, 0);
13647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  UINT startAnchor = FDKgetValidBits(bs);
13747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
13847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  FDK_ASSERT(pPce != NULL);
13947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  FDK_ASSERT(bs != NULL);
14047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  FDK_ASSERT(bytesAvailable != NULL);
14147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
14247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  if ( (startAnchor >= 24) && (*bytesAvailable >= 3)
14347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    && (FDKreadBits(bs,8) == PCE_HEIGHT_EXT_SYNC) )
14447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  {
14547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    int i;
14647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
14747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    for (i=0; i < pPce->NumFrontChannelElements; i++)
14847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    {
14947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      pPce->FrontElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
15047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    }
15147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    for (i=0; i < pPce->NumSideChannelElements; i++)
15247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    {
15347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      pPce->SideElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
15447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    }
15547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    for (i=0; i < pPce->NumBackChannelElements; i++)
15647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    {
15747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      pPce->BackElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
15847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    }
15947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    FDKbyteAlign(bs, alignmentAnchor);
16047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
16147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    FDKcrcEndReg(&crcInfo, bs, crcReg);
16247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    if ((USHORT)FDKreadBits(bs,8) != FDKcrcGetCRC(&crcInfo)) {
16347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      /* CRC failed */
16447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      err = -1;
16547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    }
16647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  }
16747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  else {
16847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    /* No valid extension data found -> restore the initial bitbuffer state */
16947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    FDKpushBack(bs, startAnchor - FDKgetValidBits(bs));
17047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  }
17147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
17247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  /* Always report the bytes read. */
17347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  *bytesAvailable -= (startAnchor - FDKgetValidBits(bs)) >> 3;
17447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
17547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  return (err);
17647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi}
17747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
1782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid CProgramConfig_Read(
1792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          CProgramConfig *pPce,
1802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          HANDLE_FDK_BITSTREAM bs,
1812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                          UINT alignmentAnchor
1822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                        )
1832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
18447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  int i, err = 0;
18547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  int commentBytes;
1862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumEffectiveChannels = 0;
1882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumChannels = 0;
1892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->ElementInstanceTag = (UCHAR) FDKreadBits(bs,4);
1902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->Profile = (UCHAR) FDKreadBits(bs,2);
1912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->SamplingFrequencyIndex = (UCHAR) FDKreadBits(bs,4);
1922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumFrontChannelElements = (UCHAR) FDKreadBits(bs,4);
1932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumSideChannelElements = (UCHAR) FDKreadBits(bs,4);
1942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumBackChannelElements = (UCHAR) FDKreadBits(bs,4);
1952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumLfeChannelElements = (UCHAR) FDKreadBits(bs,2);
1962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumAssocDataElements = (UCHAR) FDKreadBits(bs,3);
1972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumValidCcElements = (UCHAR) FDKreadBits(bs,4);
1982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ((pPce->MonoMixdownPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
2002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->MonoMixdownElementNumber = (UCHAR) FDKreadBits(bs,4);
2022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ((pPce->StereoMixdownPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
2052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->StereoMixdownElementNumber = (UCHAR) FDKreadBits(bs,4);
2072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ((pPce->MatrixMixdownIndexPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
2102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->MatrixMixdownIndex = (UCHAR) FDKreadBits(bs,2);
2122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->PseudoSurroundEnable = (UCHAR) FDKreadBits(bs,1);
2132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumFrontChannelElements; i++)
2162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->FrontElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
2182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->FrontElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
2192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1;
2202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumSideChannelElements; i++)
2232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->SideElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
2252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->SideElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
2262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1;
2272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumBackChannelElements; i++)
2302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->BackElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
2322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->BackElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
2332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1;
2342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->NumEffectiveChannels = pPce->NumChannels;
2372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumLfeChannelElements; i++)
2392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->LfeElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
2412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->NumChannels += 1;
2422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumAssocDataElements; i++)
2452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->AssocDataElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
2472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumValidCcElements; i++)
2502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->CcElementIsIndSw[i] = (UCHAR) FDKreadBits(bs,1);
2522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    pPce->ValidCcElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
2532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKbyteAlign(bs, alignmentAnchor);
2562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  pPce->CommentFieldBytes = (UCHAR) FDKreadBits(bs,8);
25847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  commentBytes = pPce->CommentFieldBytes;
25947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
26047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  /* Search for height info extension and read it if available */
26147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  err = CProgramConfig_ReadHeightExt( pPce, bs, &commentBytes, alignmentAnchor );
2622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
26347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  for (i=0; i < commentBytes; i++)
2642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
2652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    UCHAR text;
2662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    text = (UCHAR)FDKreadBits(bs,8);
2682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
2692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (i < PC_COMMENTLENGTH)
2702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
2712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      pPce->Comment[i] = text;
2722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
2732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
2742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
27547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  pPce->isValid = (err) ? 0 : 1;
2762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
2775016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
2785016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi/*
2795016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi * Compare two program configurations.
2805016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi * Returns the result of the comparison:
2815016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi *  -1 - completely different
2825016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi *   0 - completely equal
2835016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi *   1 - different but same channel configuration
2845016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi *   2 - different channel configuration but same number of channels
2855016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi */
2865016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Triviint CProgramConfig_Compare ( const CProgramConfig * const pPce1,
2875016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi                             const CProgramConfig * const pPce2 )
2885016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi{
2895016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  int result = 0;  /* Innocent until proven false. */
2905016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
2915016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  if (FDKmemcmp(pPce1, pPce2, sizeof(CProgramConfig)) != 0)
2925016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  { /* Configurations are not completely different.
2935016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi       So look into details and analyse the channel configurations: */
2945016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    result = -1;
2955016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
2965016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    if (pPce1->NumChannels == pPce2->NumChannels)
2975016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    { /* Now the logic changes. We first assume to have the same channel configuration
2985016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi         and then prove if this assumption is true. */
2995016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      result = 1;
3005016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
3015016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      /* Front channels */
3025016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      if (pPce1->NumFrontChannelElements != pPce2->NumFrontChannelElements) {
3035016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        result = 2;  /* different number of front channel elements */
3045016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      } else {
3055016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        int el, numCh1 = 0, numCh2 = 0;
3065016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        for (el = 0; el < pPce1->NumFrontChannelElements; el += 1) {
30747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          if (pPce1->FrontElementHeightInfo[el] != pPce2->FrontElementHeightInfo[el]) {
30847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            result = 2; /* different height info */
30947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            break;
31047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          }
3115016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          numCh1 += pPce1->FrontElementIsCpe[el] ? 2 : 1;
3125016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          numCh2 += pPce2->FrontElementIsCpe[el] ? 2 : 1;
3135016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        }
3145016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        if (numCh1 != numCh2) {
3155016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          result = 2;  /* different number of front channels */
3165016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        }
3175016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      }
3185016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      /* Side channels */
3195016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      if (pPce1->NumSideChannelElements != pPce2->NumSideChannelElements) {
3205016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        result = 2;  /* different number of side channel elements */
3215016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      } else {
3225016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        int el, numCh1 = 0, numCh2 = 0;
3235016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        for (el = 0; el < pPce1->NumSideChannelElements; el += 1) {
32447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          if (pPce1->SideElementHeightInfo[el] != pPce2->SideElementHeightInfo[el]) {
32547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            result = 2; /* different height info */
32647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            break;
32747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          }
3285016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          numCh1 += pPce1->SideElementIsCpe[el] ? 2 : 1;
3295016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          numCh2 += pPce2->SideElementIsCpe[el] ? 2 : 1;
3305016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        }
3315016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        if (numCh1 != numCh2) {
3325016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          result = 2;  /* different number of side channels */
3335016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        }
3345016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      }
3355016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      /* Back channels */
3365016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      if (pPce1->NumBackChannelElements != pPce2->NumBackChannelElements) {
3375016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        result = 2;  /* different number of back channel elements */
3385016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      } else {
3395016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        int el, numCh1 = 0, numCh2 = 0;
3405016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        for (el = 0; el < pPce1->NumBackChannelElements; el += 1) {
34147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          if (pPce1->BackElementHeightInfo[el] != pPce2->BackElementHeightInfo[el]) {
34247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            result = 2; /* different height info */
34347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            break;
34447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          }
3455016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          numCh1 += pPce1->BackElementIsCpe[el] ? 2 : 1;
3465016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          numCh2 += pPce2->BackElementIsCpe[el] ? 2 : 1;
3475016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        }
3485016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        if (numCh1 != numCh2) {
3495016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi          result = 2;  /* different number of back channels */
3505016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        }
3515016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      }
3525016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      /* LFE channels */
3535016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      if (pPce1->NumLfeChannelElements != pPce2->NumLfeChannelElements) {
3545016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi        result = 2;  /* different number of lfe channels */
3555016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      }
3565016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      /* LFEs are always SCEs so we don't need to count the channels. */
3575016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    }
3585016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  }
3595016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
3605016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  return result;
3615016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi}
3625016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
3635016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivivoid CProgramConfig_GetDefault( CProgramConfig *pPce,
3645016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi                                const UINT channelConfig )
3655016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi{
3665016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  FDK_ASSERT(pPce != NULL);
3675016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
3685016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  /* Init PCE */
3695016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  CProgramConfig_Init(pPce);
3705016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  pPce->Profile = 1;  /* Set AAC LC because it is the only supported object type. */
3715016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
3725016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  switch (channelConfig) {
3735016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
37447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  case 32: /* 7.1 side channel configuration as defined in FDK_audio.h */
37547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumFrontChannelElements  = 2;
37647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->FrontElementIsCpe[0]     = 0;
37747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->FrontElementIsCpe[1]     = 1;
37847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumSideChannelElements   = 1;
37947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->SideElementIsCpe[0]      = 1;
38047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumBackChannelElements   = 1;
38147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->BackElementIsCpe[0]      = 1;
38247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumLfeChannelElements    = 1;
38347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumChannels              = 8;
38447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumEffectiveChannels     = 7;
38547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->isValid                  = 1;
38647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    break;
38747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  case 12:  /* 3/0/4.1ch surround back */
38947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->BackElementIsCpe[1]      = 1;
39047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumChannels             += 1;
39147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumEffectiveChannels    += 1;
39247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  case 11:  /* 3/0/3.1ch */
39347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumFrontChannelElements += 2;
39447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->FrontElementIsCpe[0]     = 0;
39547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->FrontElementIsCpe[1]     = 1;
39647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumBackChannelElements  += 2;
39747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->BackElementIsCpe[0]      = 1;
39847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->BackElementIsCpe[1]     += 0;
39947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumLfeChannelElements   += 1;
40047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumChannels             += 7;
40147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumEffectiveChannels    += 6;
40247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->isValid                  = 1;
40347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    break;
40447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
40547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  case 14:  /* 2/0/0-3/0/2-0.1ch front height */
40647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->FrontElementHeightInfo[2] = 1;      /* Top speaker */
40747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  case 7:   /* 5/0/2.1ch front */
40847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumFrontChannelElements += 1;
40947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->FrontElementIsCpe[2]     = 1;
41047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumChannels             += 2;
41147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    pPce->NumEffectiveChannels    += 2;
4125016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  case 6:   /* 3/0/2.1ch */
4135016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumLfeChannelElements   += 1;
4145016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumChannels             += 1;
4155016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  case 5:   /* 3/0/2.0ch */
4165016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  case 4:   /* 3/0/1.0ch */
4175016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumBackChannelElements  += 1;
4185016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->BackElementIsCpe[0]      = (channelConfig>4) ? 1 : 0;
4195016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumChannels             += (channelConfig>4) ? 2 : 1;
4205016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumEffectiveChannels    += (channelConfig>4) ? 2 : 1;
4215016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  case 3:   /* 3/0/0.0ch */
4225016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumFrontChannelElements += 1;
4235016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->FrontElementIsCpe[1]     = 1;
4245016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumChannels             += 2;
4255016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumEffectiveChannels    += 2;
4265016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  case 1:   /* 1/0/0.0ch */
4275016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumFrontChannelElements += 1;
4285016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->FrontElementIsCpe[0]     = 0;
4295016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumChannels             += 1;
4305016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumEffectiveChannels    += 1;
4315016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->isValid                  = 1;
4325016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    break;
4335016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4345016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  case 2:   /* 2/0/0.ch */
4355016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumFrontChannelElements  = 1;
4365016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->FrontElementIsCpe[0]     = 1;
4375016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumChannels             += 2;
4385016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->NumEffectiveChannels    += 2;
4395016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->isValid                  = 1;
4405016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    break;
4415016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
4425016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  default:
4435016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    pPce->isValid                  = 0;   /* To be explicit! */
4445016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    break;
4455016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  }
4465016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
4475016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  if (pPce->isValid) {
4485016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    /* Create valid element instance tags */
4495016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    int el, elTagSce = 0, elTagCpe = 0;
4505016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi
4515016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
4525016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      pPce->FrontElementTagSelect[el] = (pPce->FrontElementIsCpe) ? elTagCpe++ : elTagSce++;
4535016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    }
4545016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
4555016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      pPce->SideElementTagSelect[el] = (pPce->SideElementIsCpe) ? elTagCpe++ : elTagSce++;
4565016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    }
4575016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
4585016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      pPce->BackElementTagSelect[el] = (pPce->BackElementIsCpe) ? elTagCpe++ : elTagSce++;
4595016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    }
4605016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    elTagSce = 0;
4615016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    for (el = 0; el < pPce->NumLfeChannelElements; el += 1) {
4625016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      pPce->LfeElementTagSelect[el] = elTagSce++;
4635016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    }
4645016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi  }
4655016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi}
4662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* TP_PCE_ENABLE */
4672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
4682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/**
4692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \brief get implicit audio channel type for given channelConfig and MPEG ordered channel index
47047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi * \param channelConfig MPEG channelConfiguration from 1 upto 14
4712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \param index MPEG channel order index
4722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * \return audio channel type.
4732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
47447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivistatic
4752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid getImplicitAudioChannelTypeAndIndex(
4762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        AUDIO_CHANNEL_TYPE *chType,
4772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        UCHAR *chIndex,
4782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        UINT channelConfig,
4792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        UINT index
4802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
4812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
4822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (index < 3) {
4832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *chType = ACT_FRONT;
4842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    *chIndex = index;
4852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
4862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    switch (channelConfig) {
48747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      case 4:  /* SCE, CPE, SCE */
48847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      case 5:  /* SCE, CPE, CPE */
48947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      case 6:  /* SCE, CPE, CPE, LFE */
4902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        switch (index) {
4912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          case 3:
4922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          case 4:
4932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            *chType = ACT_BACK;
4942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            *chIndex = index - 3;
4952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            break;
4962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          case 5:
4972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            *chType = ACT_LFE;
4982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            *chIndex = 0;
4992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            break;
5002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
5012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
50247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      case 7:  /* SCE,CPE,CPE,CPE,LFE */
5032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        switch (index) {
5042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          case 3:
5052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          case 4:
50647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *chType = ACT_FRONT;
50747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *chIndex = index;
5082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            break;
5092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          case 5:
5102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          case 6:
5112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            *chType = ACT_BACK;
5122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            *chIndex = index - 5;
5132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            break;
5142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          case 7:
5152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            *chType = ACT_LFE;
5162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            *chIndex = 0;
5172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            break;
5182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
5192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
52047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      case 11:  /* SCE,CPE,CPE,SCE,LFE */
52147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        if (index < 6) {
52247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *chType = ACT_BACK;
52347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *chIndex = index - 3;
52447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        } else {
52547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *chType = ACT_LFE;
52647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *chIndex = 0;
52747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        }
52847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        break;
52947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      case 12:  /* SCE,CPE,CPE,CPE,LFE */
53047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        if (index < 7) {
53147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *chType = ACT_BACK;
53247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *chIndex = index - 3;
53347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        } else {
53447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *chType = ACT_LFE;
53547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *chIndex = 0;
53647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        }
53747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        break;
53847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      case 14:  /* SCE,CPE,CPE,LFE,CPE */
53947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        switch (index) {
54047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          case 3:
54147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          case 4:
54247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *chType = ACT_BACK;
54347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *chIndex = index - 3;
54447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            break;
54547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          case 5:
54647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *chType = ACT_LFE;
54747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *chIndex = 0;
54847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            break;
54947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          case 6:
55047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          case 7:
55147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *chType = ACT_FRONT_TOP;
55247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *chIndex = index - 6;  /* handle the top layer independently */
55347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            break;
55447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        }
55547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        break;
5562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      default:
5572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *chType = ACT_NONE;
5582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
5592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
5602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
5612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
5622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
5632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint CProgramConfig_LookupElement(
5642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        CProgramConfig *pPce,
5652ddc922da87bb675b8ab8c305566436e806df0d9Jean-Michel Trivi        UINT            channelConfig,
5662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        const UINT      tag,
5672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        const UINT      channelIdx,
5682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        UCHAR           chMapping[],
5692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        AUDIO_CHANNEL_TYPE chType[],
5702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        UCHAR           chIndex[],
5712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        UCHAR          *elMapping,
5722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        MP4_ELEMENT_ID  elList[],
5732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        MP4_ELEMENT_ID  elType
5742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       )
5752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
5762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (channelConfig > 0)
5772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
5782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Constant channel mapping must have
5792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       been set during initialization. */
5802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if ( elType == ID_SCE
5812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      || elType == ID_CPE
5822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      || elType == ID_LFE )
5832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
5842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      *elMapping = pPce->elCounter;
5852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (elList[pPce->elCounter] != elType) {
5862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* Not in the list */
5872ddc922da87bb675b8ab8c305566436e806df0d9Jean-Michel Trivi        if ( (channelConfig == 2) && (elType == ID_SCE) )
5882ddc922da87bb675b8ab8c305566436e806df0d9Jean-Michel Trivi        { /* This scenario occurs with HE-AAC v2 streams of buggy encoders.
5892ddc922da87bb675b8ab8c305566436e806df0d9Jean-Michel Trivi             Due to other decoder implementations decoding of these kind of streams is desired. */
5902ddc922da87bb675b8ab8c305566436e806df0d9Jean-Michel Trivi          channelConfig = 1;
5912ddc922da87bb675b8ab8c305566436e806df0d9Jean-Michel Trivi        } else {
5922ddc922da87bb675b8ab8c305566436e806df0d9Jean-Michel Trivi          return 0;
5932ddc922da87bb675b8ab8c305566436e806df0d9Jean-Michel Trivi        }
5942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
5952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Assume all front channels */
5962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      getImplicitAudioChannelTypeAndIndex(&chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
5972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (elType == ID_CPE) {
5982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        chType[channelIdx+1] = chType[channelIdx];
5992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        chIndex[channelIdx+1] = chIndex[channelIdx]+1;
6002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
6012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      pPce->elCounter++;
6022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
6032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /* Accept all non-channel elements, too. */
6042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return 1;
6052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
6062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  else
6072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
6082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef TP_PCE_ENABLE
6092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (!pPce->isValid)
6102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* TP_PCE_ENABLE */
6112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
6122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Implicit channel mapping. */
6132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if ( elType == ID_SCE
6142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        || elType == ID_CPE
6152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        || elType == ID_LFE )
6162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
6172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* Store all channel element IDs */
6182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        elList[pPce->elCounter] = elType;
6192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        *elMapping = pPce->elCounter++;
6202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
6212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
6222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef  TP_PCE_ENABLE
6232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    else {
6242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Accept the additional channel(s), only if the tag is in the lists */
6252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      int isCpe = 0, i;
62647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      /* Element counter */
62747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      int ec[PC_NUM_HEIGHT_LAYER] = {0};
62847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      /* Channel counters */
62947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      int cc[PC_NUM_HEIGHT_LAYER] = {0};
63047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      int fc[PC_NUM_HEIGHT_LAYER] = {0};
63147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      int sc[PC_NUM_HEIGHT_LAYER] = {0};
63247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      int bc[PC_NUM_HEIGHT_LAYER] = {0};
63347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      int lc = 0;;
63447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
63547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      /* General MPEG (PCE) composition rules:
63647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi         - Over all:
63747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi             <normal height channels><top height channels><bottom height channels>
63847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi         - Within each height layer:
63947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi             <front channels><side channels><back channels>
64047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi         - Exception:
64147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi             The LFE channels have no height info and thus they are arranged at the very
64247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi             end of the normal height layer channels.
64347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi       */
6442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
6452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      switch (elType)
6462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      {
6472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case ID_CPE:
6482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        isCpe = 1;
6492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case ID_SCE:
6502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* search in front channels */
6512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i = 0; i < pPce->NumFrontChannelElements; i++) {
65247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          int heightLayer = pPce->FrontElementHeightInfo[i];
6532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (isCpe == pPce->FrontElementIsCpe[i] && pPce->FrontElementTagSelect[i] == tag) {
65447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
65547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_FRONT);
65647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            for (h = heightLayer-1; h >= 0; h-=1) {
65747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              int el;
65847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count front channels/elements */
65947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
66047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->FrontElementHeightInfo[el] == h) {
66147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
66247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
66347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
66447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
66547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count side channels/elements */
66647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
66747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->SideElementHeightInfo[el] == h) {
66847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
66947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
67047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
67147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
67247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count back channels/elements */
67347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
67447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->BackElementHeightInfo[el] == h) {
67547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
67647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
67747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
67847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
67947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              if (h == 0) {  /* normal height */
68047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                elIdx += pPce->NumLfeChannelElements;
68147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                chIdx += pPce->NumLfeChannelElements;
68247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
68347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            }
68447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chMapping[chIdx] = channelIdx;
68547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chType[chIdx] = aChType;
68647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chIndex[chIdx] = fc[heightLayer];
6872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (isCpe) {
68847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chMapping[chIdx+1] = channelIdx+1;
68947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chType[chIdx+1] = aChType;
69047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chIndex[chIdx+1] = fc[heightLayer]+1;
6912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
69247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *elMapping = elIdx;
6932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            return 1;
6942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
69547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          ec[heightLayer] += 1;
6962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (pPce->FrontElementIsCpe[i]) {
69747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            cc[heightLayer] += 2;
69847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            fc[heightLayer] += 2;
6992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          } else {
70047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            cc[heightLayer] += 1;
70147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            fc[heightLayer] += 1;
7022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
7032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
7042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* search in side channels */
7052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i = 0; i < pPce->NumSideChannelElements; i++) {
70647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          int heightLayer = pPce->SideElementHeightInfo[i];
7072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (isCpe == pPce->SideElementIsCpe[i] && pPce->SideElementTagSelect[i] == tag) {
70847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
70947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_SIDE);
71047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            for (h = heightLayer-1; h >= 0; h-=1) {
71147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              int el;
71247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count front channels/elements */
71347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
71447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->FrontElementHeightInfo[el] == h) {
71547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
71647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
71747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
71847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
71947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count side channels/elements */
72047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
72147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->SideElementHeightInfo[el] == h) {
72247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
72347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
72447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
72547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
72647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count back channels/elements */
72747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
72847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->BackElementHeightInfo[el] == h) {
72947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
73047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
73147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
73247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
73347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              if (h == 0) {  /* LFE channels belong to the normal height layer */
73447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                elIdx += pPce->NumLfeChannelElements;
73547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                chIdx += pPce->NumLfeChannelElements;
73647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
73747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            }
73847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chMapping[chIdx] = channelIdx;
73947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chType[chIdx] = aChType;
74047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chIndex[chIdx] = sc[heightLayer];
7412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (isCpe) {
74247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chMapping[chIdx+1] = channelIdx+1;
74347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chType[chIdx+1] = aChType;
74447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chIndex[chIdx+1] = sc[heightLayer]+1;
7452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
74647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *elMapping = elIdx;
7472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            return 1;
7482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
74947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          ec[heightLayer] += 1;
7502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (pPce->SideElementIsCpe[i]) {
75147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            cc[heightLayer] += 2;
75247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            sc[heightLayer] += 2;
7532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          } else {
75447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            cc[heightLayer] += 1;
75547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            sc[heightLayer] += 1;
7562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
7572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
7582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* search in back channels */
7592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i = 0; i < pPce->NumBackChannelElements; i++) {
76047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          int heightLayer = pPce->BackElementHeightInfo[i];
7612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (isCpe == pPce->BackElementIsCpe[i] && pPce->BackElementTagSelect[i] == tag) {
76247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
76347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_BACK);
76447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            for (h = heightLayer-1; h >= 0; h-=1) {
76547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              int el;
76647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count front channels/elements */
76747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
76847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->FrontElementHeightInfo[el] == h) {
76947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
77047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
77147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
77247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
77347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count side channels/elements */
77447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
77547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->SideElementHeightInfo[el] == h) {
77647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
77747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
77847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
77947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
78047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              /* Count back channels/elements */
78147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
78247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                if (pPce->BackElementHeightInfo[el] == h) {
78347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  elIdx += 1;
78447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                  chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
78547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                }
78647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
78747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              if (h == 0) {  /* normal height */
78847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                elIdx += pPce->NumLfeChannelElements;
78947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                chIdx += pPce->NumLfeChannelElements;
79047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              }
79147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            }
79247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chMapping[chIdx] = channelIdx;
79347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chType[chIdx] = aChType;
79447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chIndex[chIdx] = bc[heightLayer];
7952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            if (isCpe) {
79647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chMapping[chIdx+1] = channelIdx+1;
79747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chType[chIdx+1] = aChType;
79847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi              chIndex[chIdx+1] = bc[heightLayer]+1;
7992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            }
80047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *elMapping = elIdx;
8012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            return 1;
8022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
80347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          ec[heightLayer] += 1;
8042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (pPce->BackElementIsCpe[i]) {
80547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            cc[heightLayer] += 2;
80647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            bc[heightLayer] += 2;
8072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          } else {
80847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            cc[heightLayer] += 1;
80947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            bc[heightLayer] += 1;
8102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
8112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
8122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
8132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case ID_LFE:
81547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      { /* Unfortunately we have to go through all normal height
81647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi           layer elements to get the position of the LFE channels.
81747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi           Start with counting the front channels/elements at normal height */
81847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        for (i = 0; i < pPce->NumFrontChannelElements; i+=1) {
81947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          int heightLayer = pPce->FrontElementHeightInfo[i];
82047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          ec[heightLayer] += 1;
82147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1;
82247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        }
82347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        /* Count side channels/elements at normal height */
82447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        for (i = 0; i < pPce->NumSideChannelElements; i+=1) {
82547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          int heightLayer = pPce->SideElementHeightInfo[i];
82647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          ec[heightLayer] += 1;
82747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1;
82847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        }
82947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        /* Count back channels/elements at normal height */
83047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        for (i = 0; i < pPce->NumBackChannelElements; i+=1) {
83147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          int heightLayer = pPce->BackElementHeightInfo[i];
83247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          ec[heightLayer] += 1;
83347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1;
83447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        }
83547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
8362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* search in lfe channels */
8372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i = 0; i < pPce->NumLfeChannelElements; i++) {
83847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          int elIdx = ec[0];  /* LFE channels belong to the normal height layer */
83947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          int chIdx = cc[0];
8402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if ( pPce->LfeElementTagSelect[i] == tag ) {
84147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chMapping[chIdx] = channelIdx;
84247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            *elMapping = elIdx;
84347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chType[chIdx] = ACT_LFE;
84447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi            chIndex[chIdx] = lc;
8452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            return 1;
8462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
84747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          ec[0] += 1;
84847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          cc[0] += 1;
84947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          lc += 1;
8502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
85147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      } break;
8522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* Non audio elements */
8542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case ID_CCE:
8552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* search in cce channels */
8562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i = 0; i < pPce->NumValidCcElements; i++) {
8572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (pPce->ValidCcElementTagSelect[i] == tag) {
8582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            return 1;
8592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
8602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
8612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
8622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      case ID_DSE:
8632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        /* search associated data elements */
8642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for (i = 0; i < pPce->NumAssocDataElements; i++) {
8652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          if (pPce->AssocDataElementTagSelect[i] == tag) {
8662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project            return 1;
8672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          }
8682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
8692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
8702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      default:
8712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return 0;
8722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
8732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      return 0;  /* not found in any list */
8742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
8752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* TP_PCE_ENABLE */
8762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
8772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return 1;
8792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
8802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
8812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef  TP_PCE_ENABLE
8822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectint CProgramConfig_GetElementTable(
8832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        const CProgramConfig *pPce,
8842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        MP4_ELEMENT_ID  elList[],
88547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        const INT elListSize,
88647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        UCHAR *pChMapIdx
8872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project       )
8882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
8892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i, el = 0;
8902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
89147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  FDK_ASSERT(elList != NULL);
89247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  FDK_ASSERT(pChMapIdx != NULL);
89347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
89447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  *pChMapIdx = 0;
89547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
89647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  if ( elListSize
89747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    < pPce->NumFrontChannelElements + pPce->NumSideChannelElements + pPce->NumBackChannelElements + pPce->NumLfeChannelElements
8982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    )
8992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
9002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return 0;
9012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
9022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumFrontChannelElements; i++)
9042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
9052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    elList[el++] = (pPce->FrontElementIsCpe[i]) ?  ID_CPE : ID_SCE;
9062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
9072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumSideChannelElements; i++)
9092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
9102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    elList[el++] = (pPce->SideElementIsCpe[i]) ?  ID_CPE : ID_SCE;
9112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
9122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumBackChannelElements; i++)
9142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
9152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    elList[el++] = (pPce->BackElementIsCpe[i]) ?  ID_CPE : ID_SCE;
9162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
9172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  for (i=0; i < pPce->NumLfeChannelElements; i++)
9192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
9202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    elList[el++] = ID_LFE;
9212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
9222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
92447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  /* Find an corresponding channel configuration if possible */
92547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  switch (pPce->NumChannels) {
92647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  case 1: case 2: case 3: case 4: case 5: case 6:
92747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    /* One and two channels have no alternatives. The other ones are mapped directly to the
92847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi       corresponding channel config. Because of legacy reasons or for lack of alternative mappings. */
92947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    *pChMapIdx = pPce->NumChannels;
93047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    break;
93147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  case 7:
93247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    {
93347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
93447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      /* Create a PCE for the config to test ... */
93547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      CProgramConfig_GetDefault(tmpPce, 11);
93647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      /* ... and compare it with the given one. */
93747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce)&0xE)) ? 11 : 0;
93847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      /* If compare result is 0 or 1 we can be sure that it is channel config 11. */
93947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
94047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    }
94147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    break;
94247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  case 8:
94347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    { /* Try the four possible 7.1ch configurations. One after the other. */
94447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      UCHAR testCfg[4] = { 32, 14, 12, 7};
94547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
94647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      for (i=0; i<4; i+=1) {
94747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        /* Create a PCE for the config to test ... */
94847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        CProgramConfig_GetDefault(tmpPce, testCfg[i]);
94947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        /* ... and compare it with the given one. */
95047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        if (!(CProgramConfig_Compare(pPce, tmpPce)&0xE)) {
95147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          /* If the compare result is 0 or 1 than the two channel configurations match. */
95247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          /* Explicit mapping of 7.1 side channel configuration to 7.1 rear channel mapping. */
95347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi          *pChMapIdx = (testCfg[i]==32) ? 12 : testCfg[i];
95447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi        }
95547c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      }
95647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
95747c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    }
95847c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    break;
95947c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  default:
96047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    /* The PCE does not match any predefined channel configuration. */
96147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    *pChMapIdx = 0;
96247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    break;
96347c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi  }
96447c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi
9652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return el;
9662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
9672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
9682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic AUDIO_OBJECT_TYPE getAOT(HANDLE_FDK_BITSTREAM bs)
9702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
9712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int tmp = 0;
9722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  tmp = FDKreadBits(bs,5);
9742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (tmp == AOT_ESCAPE) {
9752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    int tmp2 = FDKreadBits(bs,6);
9762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    tmp = 32 + tmp2;
9772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
9782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (AUDIO_OBJECT_TYPE)tmp;
9802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
9812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits)
9832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
9842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  INT sampleRate;
9852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int idx;
9862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  idx = FDKreadBits(bs, nBits);
9882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if( idx == (1<<nBits)-1 ) {
9892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if(FDKgetValidBits(bs) < 24) {
9902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      return 0;
9912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
9922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sampleRate = FDKreadBits(bs,24);
9932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
9942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    sampleRate = SamplingRateTable[idx];
9952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
9962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  *index = idx;
9982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
9992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return sampleRate;
10002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
10012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef TP_GA_ENABLE
10032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
10042228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectTRANSPORTDEC_ERROR GaSpecificConfig_Parse( CSGaSpecificConfig    *self,
10052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           CSAudioSpecificConfig *asc,
10062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           HANDLE_FDK_BITSTREAM   bs,
10072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                                           UINT                   ascStartAnchor )
10082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
10092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
10102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  self->m_frameLengthFlag = FDKreadBits(bs,1);
10122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  self->m_dependsOnCoreCoder = FDKreadBits(bs,1);
10142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if( self->m_dependsOnCoreCoder )
10162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    self->m_coreCoderDelay = FDKreadBits(bs,14);
10172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  self->m_extensionFlag = FDKreadBits(bs,1);
10192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if( asc->m_channelConfiguration == 0 ) {
10212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    CProgramConfig_Read(&asc->m_progrConfigElement, bs, ascStartAnchor);
10222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
10252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    self->m_layer = FDKreadBits(bs,3);
10262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (self->m_extensionFlag) {
10292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (asc->m_aot == AOT_ER_BSAC) {
10302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      self->m_numOfSubFrame = FDKreadBits(bs,5);
10312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      self->m_layerLength   = FDKreadBits(bs,11);
10322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
10332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if ((asc->m_aot == AOT_ER_AAC_LC)   || (asc->m_aot == AOT_ER_AAC_LTP)  ||
10352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        (asc->m_aot == AOT_ER_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_LD))
10362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    {
10372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      asc->m_vcb11Flag = FDKreadBits(bs,1); /* aacSectionDataResilienceFlag */
10382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      asc->m_rvlcFlag  = FDKreadBits(bs,1); /* aacScalefactorDataResilienceFlag */
10392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      asc->m_hcrFlag   = FDKreadBits(bs,1); /* aacSpectralDataResilienceFlag */
10402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
10412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    self->m_extensionFlag3 = FDKreadBits(bs,1);
10432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (ErrorStatus);
10462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
10472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* TP_GA_ENABLE */
10482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef TP_ELD_ENABLE
10542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic INT ld_sbr_header( const CSAudioSpecificConfig *asc,
105647c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi                           HANDLE_FDK_BITSTREAM hBs,
10572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                           CSTpCallBacks *cb )
10582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
10592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  const int channelConfiguration = asc->m_channelConfiguration;
10602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int i = 0;
10612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  INT error = 0;
10622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (channelConfiguration == 2) {
10642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    error = cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
10652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
10662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    error = cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_SCE, i++);
10672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  switch ( channelConfiguration ) {
107047c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    case 14:
107147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    case 12:
10725016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    case 7:
10735016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
10745016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi    case 6:
10752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case 5:
10762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
10772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case 3:
10782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
10792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
10802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
108147c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi    case 11:
108247c680c62246594107da0a8995c953dfb8040bceJean-Michel Trivi      error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
10832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case 4:
10842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
10855016eb7f6582fbb2d72d79be782325a12df08864Jean-Michel Trivi      error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_SCE, i++);
10862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
10872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
10882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return error;
10902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
10912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
10922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectstatic
10932228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectTRANSPORTDEC_ERROR EldSpecificConfig_Parse(
10942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        CSAudioSpecificConfig *asc,
10952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        HANDLE_FDK_BITSTREAM hBs,
10962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        CSTpCallBacks *cb
10972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
10982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
10992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
11002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
11012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  ASC_ELD_EXT_TYPE eldExtType;
11022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int eldExtLen, len, cnt;
11032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(esc, sizeof(CSEldSpecificConfig));
11052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  esc->m_frameLengthFlag = FDKreadBits(hBs, 1 );
11072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (esc->m_frameLengthFlag) {
11082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    asc->m_samplesPerFrame = 480;
11092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
11102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    asc->m_samplesPerFrame = 512;
11112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
11122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  asc->m_vcb11Flag = FDKreadBits(hBs, 1 );
11142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  asc->m_rvlcFlag  = FDKreadBits(hBs, 1 );
11152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  asc->m_hcrFlag   = FDKreadBits(hBs, 1 );
11162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  esc->m_sbrPresentFlag     = FDKreadBits(hBs, 1 );
11182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (esc->m_sbrPresentFlag == 1) {
11202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    esc->m_sbrSamplingRate    = FDKreadBits(hBs, 1 ); /* 0: single rate, 1: dual rate */
11212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    esc->m_sbrCrcFlag         = FDKreadBits(hBs, 1 );
11222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    asc->m_extensionSamplingFrequency = asc->m_samplingFrequency << esc->m_sbrSamplingRate;
11242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if (cb->cbSbr != NULL){
11262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if ( 0 != ld_sbr_header(asc, hBs, cb) ) {
11272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return TRANSPORTDEC_PARSE_ERROR;
11282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
11292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
11302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
11312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  esc->m_useLdQmfTimeAlign = 0;
11322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* new ELD syntax */
11342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* parse ExtTypeConfigData */
11352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  while ((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4 )) != ELDEXT_TERM) {
11362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    eldExtLen = len = FDKreadBits(hBs, 4 );
11372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if ( len == 0xf ) {
11382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      len = FDKreadBits(hBs, 8 );
11392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      eldExtLen += len;
11402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if ( len == 0xff ) {
11422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        len = FDKreadBits(hBs, 16 );
11432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        eldExtLen += len;
11442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
11452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
11462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    switch (eldExtType) {
11482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      default:
11492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        for(cnt=0; cnt<len; cnt++) {
11502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project          FDKreadBits(hBs, 8 );
11512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        }
11522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        break;
11532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      /* add future eld extension configs here */
11542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
11552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
11562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectbail:
11572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (ErrorStatus);
11582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
11592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* TP_ELD_ENABLE */
11602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
11612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1162206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivistatic
1163206a397c708738c08edc0229881018edcb8ea793Jean-Michel TriviTRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb)
1164206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi{
1165206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi  TP_ASC_EXTENSION_ID  lastAscExt, ascExtId = ASCEXT_UNKOWN;
1166206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi  INT  bitsAvailable = (INT)FDKgetValidBits(bs);
1167206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi
1168206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi  while (bitsAvailable >= 11)
1169206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi  {
1170206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    lastAscExt = ascExtId;
1171206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    ascExtId   = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11);
1172206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    bitsAvailable -= 11;
1173206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi
1174206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    switch (ascExtId) {
1175206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    case ASCEXT_SBR:    /* 0x2b7 */
1176206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      if ( (self->m_extensionAudioObjectType != AOT_SBR) && (bitsAvailable >= 5) ) {
1177206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        self->m_extensionAudioObjectType = getAOT(bs);
1178206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi
1179206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        if ( (self->m_extensionAudioObjectType == AOT_SBR)
1180206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi          || (self->m_extensionAudioObjectType == AOT_ER_BSAC) )
1181206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        { /* Get SBR extension configuration */
1182206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi          self->m_sbrPresentFlag = FDKreadBits(bs, 1);
1183206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi          bitsAvailable -= 1;
1184206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi
1185206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi          if ( self->m_sbrPresentFlag == 1 ) {
1186206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi            self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
1187206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi
1188206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi            if ((INT)self->m_extensionSamplingFrequency <= 0) {
1189206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi              return TRANSPORTDEC_PARSE_ERROR;
1190206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi            }
1191206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi          }
1192206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi          if ( self->m_extensionAudioObjectType == AOT_ER_BSAC ) {
1193206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi            self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
1194206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi            bitsAvailable -= 4;
1195206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi          }
1196206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        }
1197206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        /* Update counter because of variable length fields (AOT and sampling rate) */
1198206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        bitsAvailable = (INT)FDKgetValidBits(bs);
1199206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      }
1200206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      break;
1201206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    case ASCEXT_PS:     /* 0x548 */
1202206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      if ( (lastAscExt == ASCEXT_SBR)
1203206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        && (self->m_extensionAudioObjectType == AOT_SBR)
1204206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        && (bitsAvailable > 0) )
1205206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      { /* Get PS extension configuration */
1206206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        self->m_psPresentFlag = FDKreadBits(bs, 1);
1207206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi        bitsAvailable -= 1;
1208206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      }
1209206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      break;
1210206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    default:
1211206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      /* Just ignore anything. */
1212206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi      return TRANSPORTDEC_OK;
1213206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    }
1214206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi  }
1215206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi
1216206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi  return TRANSPORTDEC_OK;
1217206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi}
12182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project/*
12202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project * API Functions
12212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project */
12222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Projectvoid AudioSpecificConfig_Init(CSAudioSpecificConfig *asc)
12242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
12252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  FDKmemclear(asc, sizeof(CSAudioSpecificConfig));
12262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Init all values that should not be zero. */
12282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  asc->m_aot                    = AOT_NONE;
12292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  asc->m_samplingFrequencyIndex = 0xf;
12302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  asc->m_epConfig               = -1;
12312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  asc->m_extensionAudioObjectType        = AOT_NULL_OBJECT;
12322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef TP_PCE_ENABLE
12332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  CProgramConfig_Init(&asc->m_progrConfigElement);
12342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif
12352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
12362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12372228e360595641dd906bf1773307f43d304f5b2The Android Open Source ProjectTRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
12382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        CSAudioSpecificConfig *self,
12392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        HANDLE_FDK_BITSTREAM   bs,
12402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        int                    fExplicitBackwardCompatible,
12412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        CSTpCallBacks      *cb
12422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        )
12432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project{
12442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
12452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  UINT ascStartAnchor = FDKgetValidBits(bs);
12462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  int frameLengthFlag = -1;
12472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  AudioSpecificConfig_Init(self);
12492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  self->m_aot = getAOT(bs);
12512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  self->m_samplingFrequency = getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
12522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if (self->m_samplingFrequency <= 0) {
12532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    return TRANSPORTDEC_PARSE_ERROR;
12542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
12552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  self->m_channelConfiguration = FDKreadBits(bs,4);
12572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* SBR extension ( explicit non-backwards compatible mode ) */
12592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  self->m_sbrPresentFlag = 0;
12602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  self->m_psPresentFlag  = 0;
12612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  if ( self->m_aot == AOT_SBR || self->m_aot == AOT_PS ) {
12632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    self->m_extensionAudioObjectType = AOT_SBR;
12642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    self->m_sbrPresentFlag = 1;
12662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    if ( self->m_aot == AOT_PS ) {
12672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      self->m_psPresentFlag = 1;
12682228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    }
12692228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12702228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
12712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    self->m_aot = getAOT(bs);
12722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  } else {
12742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    self->m_extensionAudioObjectType = AOT_NULL_OBJECT;
12752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
12762228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
12772228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Parse whatever specific configs */
12782228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  switch (self->m_aot)
12792228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
12802228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef TP_GA_ENABLE
12812228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_AAC_LC:
12822228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_LC:
12832228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_LD:
12842228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_SCAL:
12852228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_BSAC:
12862228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig, self, bs, ascStartAnchor)) != TRANSPORTDEC_OK ) {
12872228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return (ErrorStatus);
12882228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
12892228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag;
12902228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
12912228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* TP_GA_ENABLE */
12922228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_MPEGS:
12932228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (cb->cbSsc != NULL) {
12942228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        cb->cbSsc(
12952228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                cb->cbSscData,
12962228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                bs,
12972228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                self->m_aot,
12982228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                self->m_samplingFrequency,
12992228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                1,
13002228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                0  /* don't know the length */
13012228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project                );
13022228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      } else {
13032228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return TRANSPORTDEC_UNSUPPORTED_FORMAT;
13042228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
13052228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
13062228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#ifdef TP_ELD_ENABLE
13072228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_ELD:
13082228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK ) {
13092228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return (ErrorStatus);
13102228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
13112228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag;
13122228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag;
13132228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      self->m_extensionSamplingFrequency = (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate+1) * self->m_samplingFrequency;
13142228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
13152228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* TP_ELD_ENABLE */
13162228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13172228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    default:
13182228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
13192228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
13202228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
13212228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13222228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  /* Frame length */
13232228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  switch (self->m_aot)
13242228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
13252228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if defined(TP_GA_ENABLE) || defined(TP_USAC_ENABLE)
13262228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_AAC_LC:
13272228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_LC:
13282228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_SCAL:
13292228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_BSAC:
13302228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    /*case AOT_USAC:*/
13312228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (!frameLengthFlag)
13322228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        self->m_samplesPerFrame = 1024;
13332228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      else
13342228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        self->m_samplesPerFrame = 960;
13352228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
13362228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* TP_GA_ENABLE */
13372228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#if defined(TP_GA_ENABLE)
13382228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_LD:
13392228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (!frameLengthFlag)
13402228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        self->m_samplesPerFrame = 512;
13412228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      else
13422228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        self->m_samplesPerFrame = 480;
13432228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
13442228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project#endif /* defined(TP_GA_ENABLE) */
13452228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    default:
13462228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
13472228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
13482228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13492228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  switch (self->m_aot)
13502228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  {
13512228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_LC:
13522228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_LD:
13532228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_ELD:
13542228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_AAC_SCAL:
13552228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_CELP:
13562228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_HVXC:
13572228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    case AOT_ER_BSAC:
13582228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      self->m_epConfig = FDKreadBits(bs,2);
13592228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13602228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      if (self->m_epConfig > 1) {
13612228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project        return TRANSPORTDEC_UNSUPPORTED_FORMAT; // EPCONFIG;
13622228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      }
13632228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
13642228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project    default:
13652228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project      break;
13662228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  }
13672228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1368206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi  if (fExplicitBackwardCompatible) {
1369206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi    ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb);
1370206a397c708738c08edc0229881018edcb8ea793Jean-Michel Trivi  }
13712228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13722228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project  return (ErrorStatus);
13732228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project}
13742228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
13752228e360595641dd906bf1773307f43d304f5b2The Android Open Source Project
1376