xref: /aosp_15_r20/external/aac/libMpegTPDec/src/tpdec_latm.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /******************* MPEG transport format decoder library *********************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   Daniel Homm
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description:
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "tpdec_latm.h"
104*e5436536SAndroid Build Coastguard Worker 
105*e5436536SAndroid Build Coastguard Worker #include "FDK_bitstream.h"
106*e5436536SAndroid Build Coastguard Worker 
107*e5436536SAndroid Build Coastguard Worker #define TPDEC_TRACKINDEX(p, l) (1 * (p) + (l))
108*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs)109*e5436536SAndroid Build Coastguard Worker static UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) {
110*e5436536SAndroid Build Coastguard Worker   UCHAR bytesForValue = 0, tmp = 0;
111*e5436536SAndroid Build Coastguard Worker   int value = 0;
112*e5436536SAndroid Build Coastguard Worker 
113*e5436536SAndroid Build Coastguard Worker   bytesForValue = (UCHAR)FDKreadBits(bs, 2);
114*e5436536SAndroid Build Coastguard Worker 
115*e5436536SAndroid Build Coastguard Worker   for (UINT i = 0; i <= bytesForValue; i++) {
116*e5436536SAndroid Build Coastguard Worker     value <<= 8;
117*e5436536SAndroid Build Coastguard Worker     tmp = (UCHAR)FDKreadBits(bs, 8);
118*e5436536SAndroid Build Coastguard Worker     value += tmp;
119*e5436536SAndroid Build Coastguard Worker   }
120*e5436536SAndroid Build Coastguard Worker 
121*e5436536SAndroid Build Coastguard Worker   return value;
122*e5436536SAndroid Build Coastguard Worker }
123*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_ReadAudioMuxElement(HANDLE_FDK_BITSTREAM bs,CLatmDemux * pLatmDemux,int m_muxConfigPresent,CSTpCallBacks * pTpDecCallbacks,CSAudioSpecificConfig * pAsc,int * pfConfigFound)124*e5436536SAndroid Build Coastguard Worker static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement(
125*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, int m_muxConfigPresent,
126*e5436536SAndroid Build Coastguard Worker     CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
127*e5436536SAndroid Build Coastguard Worker     int *pfConfigFound) {
128*e5436536SAndroid Build Coastguard Worker   TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
129*e5436536SAndroid Build Coastguard Worker 
130*e5436536SAndroid Build Coastguard Worker   if (m_muxConfigPresent) {
131*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1);
132*e5436536SAndroid Build Coastguard Worker 
133*e5436536SAndroid Build Coastguard Worker     if (!pLatmDemux->m_useSameStreamMux) {
134*e5436536SAndroid Build Coastguard Worker       int i;
135*e5436536SAndroid Build Coastguard Worker       UCHAR configChanged = 0;
136*e5436536SAndroid Build Coastguard Worker       UCHAR configMode = 0;
137*e5436536SAndroid Build Coastguard Worker 
138*e5436536SAndroid Build Coastguard Worker       FDK_BITSTREAM bsAnchor;
139*e5436536SAndroid Build Coastguard Worker 
140*e5436536SAndroid Build Coastguard Worker       FDK_BITSTREAM bsAnchorDummyParse;
141*e5436536SAndroid Build Coastguard Worker 
142*e5436536SAndroid Build Coastguard Worker       if (!pLatmDemux->applyAsc) {
143*e5436536SAndroid Build Coastguard Worker         bsAnchorDummyParse = *bs;
144*e5436536SAndroid Build Coastguard Worker         pLatmDemux->newCfgHasAudioPreRoll = 0;
145*e5436536SAndroid Build Coastguard Worker         /* do dummy-parsing of ASC to determine if there is an audioPreRoll */
146*e5436536SAndroid Build Coastguard Worker         configMode |= AC_CM_DET_CFG_CHANGE;
147*e5436536SAndroid Build Coastguard Worker         if (TRANSPORTDEC_OK !=
148*e5436536SAndroid Build Coastguard Worker             (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
149*e5436536SAndroid Build Coastguard Worker                  bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
150*e5436536SAndroid Build Coastguard Worker                  configMode, configChanged))) {
151*e5436536SAndroid Build Coastguard Worker           goto bail;
152*e5436536SAndroid Build Coastguard Worker         }
153*e5436536SAndroid Build Coastguard Worker 
154*e5436536SAndroid Build Coastguard Worker         /* Allow flushing only when audioPreroll functionality is enabled in
155*e5436536SAndroid Build Coastguard Worker          * current and new config otherwise the new config can be applied
156*e5436536SAndroid Build Coastguard Worker          * immediately. */
157*e5436536SAndroid Build Coastguard Worker         if (pAsc->m_sc.m_usacConfig.element[0]
158*e5436536SAndroid Build Coastguard Worker                 .extElement.usacExtElementHasAudioPreRoll &&
159*e5436536SAndroid Build Coastguard Worker             pLatmDemux->newCfgHasAudioPreRoll) {
160*e5436536SAndroid Build Coastguard Worker           pLatmDemux->newCfgHasAudioPreRoll = 0;
161*e5436536SAndroid Build Coastguard Worker           /* with audioPreRoll we must flush before applying new cfg */
162*e5436536SAndroid Build Coastguard Worker           pLatmDemux->applyAsc = 0;
163*e5436536SAndroid Build Coastguard Worker         } else {
164*e5436536SAndroid Build Coastguard Worker           *bs = bsAnchorDummyParse;
165*e5436536SAndroid Build Coastguard Worker           pLatmDemux->applyAsc = 1; /* apply new config immediate */
166*e5436536SAndroid Build Coastguard Worker         }
167*e5436536SAndroid Build Coastguard Worker       }
168*e5436536SAndroid Build Coastguard Worker 
169*e5436536SAndroid Build Coastguard Worker       if (pLatmDemux->applyAsc) {
170*e5436536SAndroid Build Coastguard Worker         for (i = 0; i < 2; i++) {
171*e5436536SAndroid Build Coastguard Worker           configMode = 0;
172*e5436536SAndroid Build Coastguard Worker 
173*e5436536SAndroid Build Coastguard Worker           if (i == 0) {
174*e5436536SAndroid Build Coastguard Worker             configMode |= AC_CM_DET_CFG_CHANGE;
175*e5436536SAndroid Build Coastguard Worker             bsAnchor = *bs;
176*e5436536SAndroid Build Coastguard Worker           } else {
177*e5436536SAndroid Build Coastguard Worker             configMode |= AC_CM_ALLOC_MEM;
178*e5436536SAndroid Build Coastguard Worker             *bs = bsAnchor;
179*e5436536SAndroid Build Coastguard Worker           }
180*e5436536SAndroid Build Coastguard Worker 
181*e5436536SAndroid Build Coastguard Worker           if (TRANSPORTDEC_OK !=
182*e5436536SAndroid Build Coastguard Worker               (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
183*e5436536SAndroid Build Coastguard Worker                    bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
184*e5436536SAndroid Build Coastguard Worker                    configMode, configChanged))) {
185*e5436536SAndroid Build Coastguard Worker             goto bail;
186*e5436536SAndroid Build Coastguard Worker           }
187*e5436536SAndroid Build Coastguard Worker 
188*e5436536SAndroid Build Coastguard Worker           if (ErrorStatus == TRANSPORTDEC_OK) {
189*e5436536SAndroid Build Coastguard Worker             if ((i == 0) && (pAsc->AacConfigChanged || pAsc->SbrConfigChanged ||
190*e5436536SAndroid Build Coastguard Worker                              pAsc->SacConfigChanged)) {
191*e5436536SAndroid Build Coastguard Worker               int errC;
192*e5436536SAndroid Build Coastguard Worker 
193*e5436536SAndroid Build Coastguard Worker               configChanged = 1;
194*e5436536SAndroid Build Coastguard Worker               errC = pTpDecCallbacks->cbFreeMem(pTpDecCallbacks->cbFreeMemData,
195*e5436536SAndroid Build Coastguard Worker                                                 pAsc);
196*e5436536SAndroid Build Coastguard Worker               if (errC != 0) {
197*e5436536SAndroid Build Coastguard Worker                 ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
198*e5436536SAndroid Build Coastguard Worker                 goto bail;
199*e5436536SAndroid Build Coastguard Worker               }
200*e5436536SAndroid Build Coastguard Worker             }
201*e5436536SAndroid Build Coastguard Worker           }
202*e5436536SAndroid Build Coastguard Worker         }
203*e5436536SAndroid Build Coastguard Worker       }
204*e5436536SAndroid Build Coastguard Worker     }
205*e5436536SAndroid Build Coastguard Worker   }
206*e5436536SAndroid Build Coastguard Worker 
207*e5436536SAndroid Build Coastguard Worker   /* If there was no configuration read, its not possible to parse
208*e5436536SAndroid Build Coastguard Worker    * PayloadLengthInfo below. */
209*e5436536SAndroid Build Coastguard Worker   if (!*pfConfigFound) {
210*e5436536SAndroid Build Coastguard Worker     ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
211*e5436536SAndroid Build Coastguard Worker     goto bail;
212*e5436536SAndroid Build Coastguard Worker   }
213*e5436536SAndroid Build Coastguard Worker 
214*e5436536SAndroid Build Coastguard Worker   if (pLatmDemux->m_AudioMuxVersionA == 0) {
215*e5436536SAndroid Build Coastguard Worker     /* Do only once per call, because parsing and decoding is done in-line. */
216*e5436536SAndroid Build Coastguard Worker     if (TRANSPORTDEC_OK !=
217*e5436536SAndroid Build Coastguard Worker         (ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs, pLatmDemux))) {
218*e5436536SAndroid Build Coastguard Worker       *pfConfigFound = 0;
219*e5436536SAndroid Build Coastguard Worker       goto bail;
220*e5436536SAndroid Build Coastguard Worker     }
221*e5436536SAndroid Build Coastguard Worker   } else {
222*e5436536SAndroid Build Coastguard Worker     /* audioMuxVersionA > 0 is reserved for future extensions */
223*e5436536SAndroid Build Coastguard Worker     ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
224*e5436536SAndroid Build Coastguard Worker     *pfConfigFound = 0;
225*e5436536SAndroid Build Coastguard Worker     goto bail;
226*e5436536SAndroid Build Coastguard Worker   }
227*e5436536SAndroid Build Coastguard Worker 
228*e5436536SAndroid Build Coastguard Worker bail:
229*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != TRANSPORTDEC_OK) {
230*e5436536SAndroid Build Coastguard Worker     pLatmDemux->applyAsc = 1;
231*e5436536SAndroid Build Coastguard Worker   }
232*e5436536SAndroid Build Coastguard Worker 
233*e5436536SAndroid Build Coastguard Worker   return (ErrorStatus);
234*e5436536SAndroid Build Coastguard Worker }
235*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,CLatmDemux * pLatmDemux,TRANSPORT_TYPE tt,CSTpCallBacks * pTpDecCallbacks,CSAudioSpecificConfig * pAsc,int * pfConfigFound,const INT ignoreBufferFullness)236*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,
237*e5436536SAndroid Build Coastguard Worker                                    CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt,
238*e5436536SAndroid Build Coastguard Worker                                    CSTpCallBacks *pTpDecCallbacks,
239*e5436536SAndroid Build Coastguard Worker                                    CSAudioSpecificConfig *pAsc,
240*e5436536SAndroid Build Coastguard Worker                                    int *pfConfigFound,
241*e5436536SAndroid Build Coastguard Worker                                    const INT ignoreBufferFullness) {
242*e5436536SAndroid Build Coastguard Worker   UINT cntBits;
243*e5436536SAndroid Build Coastguard Worker   UINT cmpBufferFullness;
244*e5436536SAndroid Build Coastguard Worker   UINT audioMuxLengthBytesLast = 0;
245*e5436536SAndroid Build Coastguard Worker   TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
246*e5436536SAndroid Build Coastguard Worker 
247*e5436536SAndroid Build Coastguard Worker   cntBits = FDKgetValidBits(bs);
248*e5436536SAndroid Build Coastguard Worker 
249*e5436536SAndroid Build Coastguard Worker   if ((INT)cntBits < MIN_LATM_HEADERLENGTH) {
250*e5436536SAndroid Build Coastguard Worker     return TRANSPORTDEC_NOT_ENOUGH_BITS;
251*e5436536SAndroid Build Coastguard Worker   }
252*e5436536SAndroid Build Coastguard Worker 
253*e5436536SAndroid Build Coastguard Worker   if (TRANSPORTDEC_OK != (ErrorStatus = CLatmDemux_ReadAudioMuxElement(
254*e5436536SAndroid Build Coastguard Worker                               bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0),
255*e5436536SAndroid Build Coastguard Worker                               pTpDecCallbacks, pAsc, pfConfigFound)))
256*e5436536SAndroid Build Coastguard Worker     return (ErrorStatus);
257*e5436536SAndroid Build Coastguard Worker 
258*e5436536SAndroid Build Coastguard Worker   if (!ignoreBufferFullness) {
259*e5436536SAndroid Build Coastguard Worker     cmpBufferFullness =
260*e5436536SAndroid Build Coastguard Worker         24 + audioMuxLengthBytesLast * 8 +
261*e5436536SAndroid Build Coastguard Worker         pLatmDemux->m_linfo[0][0].m_bufferFullness *
262*e5436536SAndroid Build Coastguard Worker             pAsc[TPDEC_TRACKINDEX(0, 0)].m_channelConfiguration * 32;
263*e5436536SAndroid Build Coastguard Worker 
264*e5436536SAndroid Build Coastguard Worker     /* evaluate buffer fullness */
265*e5436536SAndroid Build Coastguard Worker 
266*e5436536SAndroid Build Coastguard Worker     if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) {
267*e5436536SAndroid Build Coastguard Worker       if (!pLatmDemux->BufferFullnessAchieved) {
268*e5436536SAndroid Build Coastguard Worker         if (cntBits < cmpBufferFullness) {
269*e5436536SAndroid Build Coastguard Worker           /* condition for start of decoding is not fulfilled */
270*e5436536SAndroid Build Coastguard Worker 
271*e5436536SAndroid Build Coastguard Worker           /* the current frame will not be decoded */
272*e5436536SAndroid Build Coastguard Worker           return TRANSPORTDEC_NOT_ENOUGH_BITS;
273*e5436536SAndroid Build Coastguard Worker         } else {
274*e5436536SAndroid Build Coastguard Worker           pLatmDemux->BufferFullnessAchieved = 1;
275*e5436536SAndroid Build Coastguard Worker         }
276*e5436536SAndroid Build Coastguard Worker       }
277*e5436536SAndroid Build Coastguard Worker     }
278*e5436536SAndroid Build Coastguard Worker   }
279*e5436536SAndroid Build Coastguard Worker 
280*e5436536SAndroid Build Coastguard Worker   return (ErrorStatus);
281*e5436536SAndroid Build Coastguard Worker }
282*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_ReadStreamMuxConfig(HANDLE_FDK_BITSTREAM bs,CLatmDemux * pLatmDemux,CSTpCallBacks * pTpDecCallbacks,CSAudioSpecificConfig * pAsc,int * pfConfigFound,UCHAR configMode,UCHAR configChanged)283*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
284*e5436536SAndroid Build Coastguard Worker     HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux,
285*e5436536SAndroid Build Coastguard Worker     CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
286*e5436536SAndroid Build Coastguard Worker     int *pfConfigFound, UCHAR configMode, UCHAR configChanged) {
287*e5436536SAndroid Build Coastguard Worker   CSAudioSpecificConfig ascDummy; /* the actual config is needed for flushing,
288*e5436536SAndroid Build Coastguard Worker                                      after that new config can be parsed */
289*e5436536SAndroid Build Coastguard Worker   CSAudioSpecificConfig *pAscDummy;
290*e5436536SAndroid Build Coastguard Worker   pAscDummy = &ascDummy;
291*e5436536SAndroid Build Coastguard Worker   pLatmDemux->usacExplicitCfgChanged = 0;
292*e5436536SAndroid Build Coastguard Worker   LATM_LAYER_INFO *p_linfo = NULL;
293*e5436536SAndroid Build Coastguard Worker   TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
294*e5436536SAndroid Build Coastguard Worker   UCHAR updateConfig[1 * 1] = {0};
295*e5436536SAndroid Build Coastguard Worker 
296*e5436536SAndroid Build Coastguard Worker   pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs, 1);
297*e5436536SAndroid Build Coastguard Worker 
298*e5436536SAndroid Build Coastguard Worker   if (pLatmDemux->m_AudioMuxVersion == 0) {
299*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_AudioMuxVersionA = 0;
300*e5436536SAndroid Build Coastguard Worker   } else {
301*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs, 1);
302*e5436536SAndroid Build Coastguard Worker   }
303*e5436536SAndroid Build Coastguard Worker 
304*e5436536SAndroid Build Coastguard Worker   if (pLatmDemux->m_AudioMuxVersionA == 0) {
305*e5436536SAndroid Build Coastguard Worker     if (pLatmDemux->m_AudioMuxVersion == 1) {
306*e5436536SAndroid Build Coastguard Worker       pLatmDemux->m_taraBufferFullness = CLatmDemux_GetValue(bs);
307*e5436536SAndroid Build Coastguard Worker     }
308*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs, 1);
309*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_noSubFrames = FDKreadBits(bs, 6) + 1;
310*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_numProgram = FDKreadBits(bs, 4) + 1;
311*e5436536SAndroid Build Coastguard Worker 
312*e5436536SAndroid Build Coastguard Worker     if (pLatmDemux->m_numProgram > LATM_MAX_PROG) {
313*e5436536SAndroid Build Coastguard Worker       ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
314*e5436536SAndroid Build Coastguard Worker       goto bail;
315*e5436536SAndroid Build Coastguard Worker     }
316*e5436536SAndroid Build Coastguard Worker 
317*e5436536SAndroid Build Coastguard Worker     int idCnt = 0;
318*e5436536SAndroid Build Coastguard Worker     for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
319*e5436536SAndroid Build Coastguard Worker       pLatmDemux->m_numLayer[prog] = FDKreadBits(bs, 3) + 1;
320*e5436536SAndroid Build Coastguard Worker       if (pLatmDemux->m_numLayer[prog] > LATM_MAX_LAYER) {
321*e5436536SAndroid Build Coastguard Worker         ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
322*e5436536SAndroid Build Coastguard Worker         goto bail;
323*e5436536SAndroid Build Coastguard Worker       }
324*e5436536SAndroid Build Coastguard Worker 
325*e5436536SAndroid Build Coastguard Worker       for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
326*e5436536SAndroid Build Coastguard Worker         int useSameConfig;
327*e5436536SAndroid Build Coastguard Worker         p_linfo = &pLatmDemux->m_linfo[prog][lay];
328*e5436536SAndroid Build Coastguard Worker 
329*e5436536SAndroid Build Coastguard Worker         p_linfo->m_streamID = idCnt++;
330*e5436536SAndroid Build Coastguard Worker         p_linfo->m_frameLengthInBits = 0;
331*e5436536SAndroid Build Coastguard Worker 
332*e5436536SAndroid Build Coastguard Worker         if ((prog == 0) && (lay == 0)) {
333*e5436536SAndroid Build Coastguard Worker           useSameConfig = 0;
334*e5436536SAndroid Build Coastguard Worker         } else {
335*e5436536SAndroid Build Coastguard Worker           useSameConfig = FDKreadBits(bs, 1);
336*e5436536SAndroid Build Coastguard Worker         }
337*e5436536SAndroid Build Coastguard Worker 
338*e5436536SAndroid Build Coastguard Worker         if (useSameConfig) {
339*e5436536SAndroid Build Coastguard Worker           if (lay > 0) {
340*e5436536SAndroid Build Coastguard Worker             FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)],
341*e5436536SAndroid Build Coastguard Worker                       &pAsc[TPDEC_TRACKINDEX(prog, lay - 1)],
342*e5436536SAndroid Build Coastguard Worker                       sizeof(CSAudioSpecificConfig));
343*e5436536SAndroid Build Coastguard Worker           } else {
344*e5436536SAndroid Build Coastguard Worker             ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
345*e5436536SAndroid Build Coastguard Worker             goto bail;
346*e5436536SAndroid Build Coastguard Worker           }
347*e5436536SAndroid Build Coastguard Worker         } else {
348*e5436536SAndroid Build Coastguard Worker           UINT usacConfigLengthPrev = 0;
349*e5436536SAndroid Build Coastguard Worker           UCHAR usacConfigPrev[TP_USAC_MAX_CONFIG_LEN];
350*e5436536SAndroid Build Coastguard Worker 
351*e5436536SAndroid Build Coastguard Worker           if (!(pLatmDemux->applyAsc) &&
352*e5436536SAndroid Build Coastguard Worker               (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_USAC)) {
353*e5436536SAndroid Build Coastguard Worker             usacConfigLengthPrev =
354*e5436536SAndroid Build Coastguard Worker                 (UINT)(pAsc[TPDEC_TRACKINDEX(prog, lay)]
355*e5436536SAndroid Build Coastguard Worker                            .m_sc.m_usacConfig.UsacConfigBits +
356*e5436536SAndroid Build Coastguard Worker                        7) >>
357*e5436536SAndroid Build Coastguard Worker                 3; /* store previous USAC config length */
358*e5436536SAndroid Build Coastguard Worker             if (usacConfigLengthPrev > TP_USAC_MAX_CONFIG_LEN) {
359*e5436536SAndroid Build Coastguard Worker               ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
360*e5436536SAndroid Build Coastguard Worker               goto bail;
361*e5436536SAndroid Build Coastguard Worker             }
362*e5436536SAndroid Build Coastguard Worker             FDKmemclear(usacConfigPrev, TP_USAC_MAX_CONFIG_LEN);
363*e5436536SAndroid Build Coastguard Worker             FDKmemcpy(
364*e5436536SAndroid Build Coastguard Worker                 usacConfigPrev,
365*e5436536SAndroid Build Coastguard Worker                 &pAsc[TPDEC_TRACKINDEX(prog, lay)].m_sc.m_usacConfig.UsacConfig,
366*e5436536SAndroid Build Coastguard Worker                 usacConfigLengthPrev); /* store previous USAC config */
367*e5436536SAndroid Build Coastguard Worker           }
368*e5436536SAndroid Build Coastguard Worker           if (pLatmDemux->m_AudioMuxVersion == 1) {
369*e5436536SAndroid Build Coastguard Worker             FDK_BITSTREAM tmpBs;
370*e5436536SAndroid Build Coastguard Worker             INT ascLen = 0;
371*e5436536SAndroid Build Coastguard Worker             ascLen = CLatmDemux_GetValue(bs);
372*e5436536SAndroid Build Coastguard Worker             /* The ascLen could be wrong, so check if validBits<=bufBits*/
373*e5436536SAndroid Build Coastguard Worker             if (ascLen < 0 || ascLen > (INT)FDKgetValidBits(bs)) {
374*e5436536SAndroid Build Coastguard Worker               ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
375*e5436536SAndroid Build Coastguard Worker               goto bail;
376*e5436536SAndroid Build Coastguard Worker             }
377*e5436536SAndroid Build Coastguard Worker             FDKsyncCache(bs);
378*e5436536SAndroid Build Coastguard Worker             tmpBs = *bs;
379*e5436536SAndroid Build Coastguard Worker             tmpBs.hBitBuf.ValidBits = ascLen;
380*e5436536SAndroid Build Coastguard Worker 
381*e5436536SAndroid Build Coastguard Worker             /* Read ASC */
382*e5436536SAndroid Build Coastguard Worker             if (pLatmDemux->applyAsc) {
383*e5436536SAndroid Build Coastguard Worker               if (TRANSPORTDEC_OK !=
384*e5436536SAndroid Build Coastguard Worker                   (ErrorStatus = AudioSpecificConfig_Parse(
385*e5436536SAndroid Build Coastguard Worker                        &pAsc[TPDEC_TRACKINDEX(prog, lay)], &tmpBs, 1,
386*e5436536SAndroid Build Coastguard Worker                        pTpDecCallbacks, configMode, configChanged,
387*e5436536SAndroid Build Coastguard Worker                        AOT_NULL_OBJECT)))
388*e5436536SAndroid Build Coastguard Worker                 goto bail;
389*e5436536SAndroid Build Coastguard Worker             } else {
390*e5436536SAndroid Build Coastguard Worker               if (TRANSPORTDEC_OK !=
391*e5436536SAndroid Build Coastguard Worker                   (ErrorStatus = AudioSpecificConfig_Parse(
392*e5436536SAndroid Build Coastguard Worker                        pAscDummy, &tmpBs, 1, pTpDecCallbacks, configMode,
393*e5436536SAndroid Build Coastguard Worker                        configChanged, AOT_NULL_OBJECT)))
394*e5436536SAndroid Build Coastguard Worker                 goto bail;
395*e5436536SAndroid Build Coastguard Worker             }
396*e5436536SAndroid Build Coastguard Worker 
397*e5436536SAndroid Build Coastguard Worker             /* The field p_linfo->m_ascLen could be wrong, so check if */
398*e5436536SAndroid Build Coastguard Worker             if (0 > (INT)FDKgetValidBits(&tmpBs)) {
399*e5436536SAndroid Build Coastguard Worker               ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
400*e5436536SAndroid Build Coastguard Worker               goto bail;
401*e5436536SAndroid Build Coastguard Worker             }
402*e5436536SAndroid Build Coastguard Worker             FDKpushFor(bs, ascLen); /* position bitstream after ASC */
403*e5436536SAndroid Build Coastguard Worker           } else {
404*e5436536SAndroid Build Coastguard Worker             /* Read ASC */
405*e5436536SAndroid Build Coastguard Worker             if (pLatmDemux->applyAsc) {
406*e5436536SAndroid Build Coastguard Worker               if (TRANSPORTDEC_OK != (ErrorStatus = AudioSpecificConfig_Parse(
407*e5436536SAndroid Build Coastguard Worker                                           &pAsc[TPDEC_TRACKINDEX(prog, lay)],
408*e5436536SAndroid Build Coastguard Worker                                           bs, 0, pTpDecCallbacks, configMode,
409*e5436536SAndroid Build Coastguard Worker                                           configChanged, AOT_NULL_OBJECT)))
410*e5436536SAndroid Build Coastguard Worker                 goto bail;
411*e5436536SAndroid Build Coastguard Worker             } else {
412*e5436536SAndroid Build Coastguard Worker               if (TRANSPORTDEC_OK !=
413*e5436536SAndroid Build Coastguard Worker                   (ErrorStatus = AudioSpecificConfig_Parse(
414*e5436536SAndroid Build Coastguard Worker                        pAscDummy, bs, 0, pTpDecCallbacks, configMode,
415*e5436536SAndroid Build Coastguard Worker                        configChanged, AOT_NULL_OBJECT)))
416*e5436536SAndroid Build Coastguard Worker                 goto bail;
417*e5436536SAndroid Build Coastguard Worker             }
418*e5436536SAndroid Build Coastguard Worker           }
419*e5436536SAndroid Build Coastguard Worker           if (!pLatmDemux->applyAsc) {
420*e5436536SAndroid Build Coastguard Worker             updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 0;
421*e5436536SAndroid Build Coastguard Worker           } else {
422*e5436536SAndroid Build Coastguard Worker             updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 1;
423*e5436536SAndroid Build Coastguard Worker           }
424*e5436536SAndroid Build Coastguard Worker 
425*e5436536SAndroid Build Coastguard Worker           if (!pLatmDemux->applyAsc) {
426*e5436536SAndroid Build Coastguard Worker             if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
427*e5436536SAndroid Build Coastguard Worker                 AOT_USAC) { /* flush in case SMC has changed */
428*e5436536SAndroid Build Coastguard Worker               const UINT usacConfigLength =
429*e5436536SAndroid Build Coastguard Worker                   (UINT)(pAscDummy->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3;
430*e5436536SAndroid Build Coastguard Worker               if (usacConfigLength > TP_USAC_MAX_CONFIG_LEN) {
431*e5436536SAndroid Build Coastguard Worker                 ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
432*e5436536SAndroid Build Coastguard Worker                 goto bail;
433*e5436536SAndroid Build Coastguard Worker               }
434*e5436536SAndroid Build Coastguard Worker               if (usacConfigLength != usacConfigLengthPrev) {
435*e5436536SAndroid Build Coastguard Worker                 FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
436*e5436536SAndroid Build Coastguard Worker                                  .m_sc.m_usacConfig.UsacConfig,
437*e5436536SAndroid Build Coastguard Worker                             TP_USAC_MAX_CONFIG_LEN);
438*e5436536SAndroid Build Coastguard Worker                 FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
439*e5436536SAndroid Build Coastguard Worker                                .m_sc.m_usacConfig.UsacConfig,
440*e5436536SAndroid Build Coastguard Worker                           &pAscDummy->m_sc.m_usacConfig.UsacConfig,
441*e5436536SAndroid Build Coastguard Worker                           usacConfigLength); /* store new USAC config */
442*e5436536SAndroid Build Coastguard Worker                 pAsc[TPDEC_TRACKINDEX(prog, lay)]
443*e5436536SAndroid Build Coastguard Worker                     .m_sc.m_usacConfig.UsacConfigBits =
444*e5436536SAndroid Build Coastguard Worker                     pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
445*e5436536SAndroid Build Coastguard Worker                 pLatmDemux->usacExplicitCfgChanged = 1;
446*e5436536SAndroid Build Coastguard Worker               } else {
447*e5436536SAndroid Build Coastguard Worker                 if (FDKmemcmp(usacConfigPrev,
448*e5436536SAndroid Build Coastguard Worker                               pAscDummy->m_sc.m_usacConfig.UsacConfig,
449*e5436536SAndroid Build Coastguard Worker                               usacConfigLengthPrev)) {
450*e5436536SAndroid Build Coastguard Worker                   FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
451*e5436536SAndroid Build Coastguard Worker                                    .m_sc.m_usacConfig.UsacConfig,
452*e5436536SAndroid Build Coastguard Worker                               TP_USAC_MAX_CONFIG_LEN);
453*e5436536SAndroid Build Coastguard Worker                   FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
454*e5436536SAndroid Build Coastguard Worker                                  .m_sc.m_usacConfig.UsacConfig,
455*e5436536SAndroid Build Coastguard Worker                             &pAscDummy->m_sc.m_usacConfig.UsacConfig,
456*e5436536SAndroid Build Coastguard Worker                             usacConfigLength); /* store new USAC config */
457*e5436536SAndroid Build Coastguard Worker                   pAsc[TPDEC_TRACKINDEX(prog, lay)]
458*e5436536SAndroid Build Coastguard Worker                       .m_sc.m_usacConfig.UsacConfigBits =
459*e5436536SAndroid Build Coastguard Worker                       pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
460*e5436536SAndroid Build Coastguard Worker                   pLatmDemux->usacExplicitCfgChanged = 1;
461*e5436536SAndroid Build Coastguard Worker                 }
462*e5436536SAndroid Build Coastguard Worker               }
463*e5436536SAndroid Build Coastguard Worker 
464*e5436536SAndroid Build Coastguard Worker               if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
465*e5436536SAndroid Build Coastguard Worker                       .m_sc.m_usacConfig.m_usacNumElements) {
466*e5436536SAndroid Build Coastguard Worker                 if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
467*e5436536SAndroid Build Coastguard Worker                         .m_sc.m_usacConfig.element[0]
468*e5436536SAndroid Build Coastguard Worker                         .extElement.usacExtElementHasAudioPreRoll) {
469*e5436536SAndroid Build Coastguard Worker                   pLatmDemux->newCfgHasAudioPreRoll =
470*e5436536SAndroid Build Coastguard Worker                       1; /* if dummy parsed cfg has audioPreRoll we first flush
471*e5436536SAndroid Build Coastguard Worker                             before applying new cfg */
472*e5436536SAndroid Build Coastguard Worker                 }
473*e5436536SAndroid Build Coastguard Worker               }
474*e5436536SAndroid Build Coastguard Worker             }
475*e5436536SAndroid Build Coastguard Worker           }
476*e5436536SAndroid Build Coastguard Worker         }
477*e5436536SAndroid Build Coastguard Worker 
478*e5436536SAndroid Build Coastguard Worker         p_linfo->m_frameLengthType = FDKreadBits(bs, 3);
479*e5436536SAndroid Build Coastguard Worker         switch (p_linfo->m_frameLengthType) {
480*e5436536SAndroid Build Coastguard Worker           case 0:
481*e5436536SAndroid Build Coastguard Worker             p_linfo->m_bufferFullness = FDKreadBits(bs, 8);
482*e5436536SAndroid Build Coastguard Worker 
483*e5436536SAndroid Build Coastguard Worker             if (!pLatmDemux->m_allStreamsSameTimeFraming) {
484*e5436536SAndroid Build Coastguard Worker               if ((lay > 0) &&
485*e5436536SAndroid Build Coastguard Worker                   (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_AAC_SCAL ||
486*e5436536SAndroid Build Coastguard Worker                    pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
487*e5436536SAndroid Build Coastguard Worker                        AOT_ER_AAC_SCAL) &&
488*e5436536SAndroid Build Coastguard Worker                   (pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == AOT_CELP ||
489*e5436536SAndroid Build Coastguard Worker                    pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot ==
490*e5436536SAndroid Build Coastguard Worker                        AOT_ER_CELP)) { /* The layer maybe
491*e5436536SAndroid Build Coastguard Worker                                           ignored later so
492*e5436536SAndroid Build Coastguard Worker                                           read it anyway: */
493*e5436536SAndroid Build Coastguard Worker                 /* coreFrameOffset = */ FDKreadBits(bs, 6);
494*e5436536SAndroid Build Coastguard Worker               }
495*e5436536SAndroid Build Coastguard Worker             }
496*e5436536SAndroid Build Coastguard Worker             break;
497*e5436536SAndroid Build Coastguard Worker           case 1:
498*e5436536SAndroid Build Coastguard Worker             p_linfo->m_frameLengthInBits = FDKreadBits(bs, 9);
499*e5436536SAndroid Build Coastguard Worker             break;
500*e5436536SAndroid Build Coastguard Worker           case 3:
501*e5436536SAndroid Build Coastguard Worker           case 4:
502*e5436536SAndroid Build Coastguard Worker           case 5:
503*e5436536SAndroid Build Coastguard Worker             /* CELP */
504*e5436536SAndroid Build Coastguard Worker           case 6:
505*e5436536SAndroid Build Coastguard Worker           case 7:
506*e5436536SAndroid Build Coastguard Worker             /* HVXC */
507*e5436536SAndroid Build Coastguard Worker           default:
508*e5436536SAndroid Build Coastguard Worker             ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
509*e5436536SAndroid Build Coastguard Worker             goto bail;
510*e5436536SAndroid Build Coastguard Worker         } /* switch framelengthtype*/
511*e5436536SAndroid Build Coastguard Worker 
512*e5436536SAndroid Build Coastguard Worker       } /* layer loop */
513*e5436536SAndroid Build Coastguard Worker     }   /* prog loop */
514*e5436536SAndroid Build Coastguard Worker 
515*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_otherDataPresent = FDKreadBits(bs, 1);
516*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_otherDataLength = 0;
517*e5436536SAndroid Build Coastguard Worker 
518*e5436536SAndroid Build Coastguard Worker     if (pLatmDemux->m_otherDataPresent) {
519*e5436536SAndroid Build Coastguard Worker       if (pLatmDemux->m_AudioMuxVersion == 1) {
520*e5436536SAndroid Build Coastguard Worker         pLatmDemux->m_otherDataLength = CLatmDemux_GetValue(bs);
521*e5436536SAndroid Build Coastguard Worker       } else {
522*e5436536SAndroid Build Coastguard Worker         int otherDataLenEsc = 0;
523*e5436536SAndroid Build Coastguard Worker         do {
524*e5436536SAndroid Build Coastguard Worker           pLatmDemux->m_otherDataLength <<= 8;  // *= 256
525*e5436536SAndroid Build Coastguard Worker           otherDataLenEsc = FDKreadBits(bs, 1);
526*e5436536SAndroid Build Coastguard Worker           pLatmDemux->m_otherDataLength += FDKreadBits(bs, 8);
527*e5436536SAndroid Build Coastguard Worker         } while (otherDataLenEsc);
528*e5436536SAndroid Build Coastguard Worker       }
529*e5436536SAndroid Build Coastguard Worker       if (pLatmDemux->m_audioMuxLengthBytes <
530*e5436536SAndroid Build Coastguard Worker           (pLatmDemux->m_otherDataLength >> 3)) {
531*e5436536SAndroid Build Coastguard Worker         ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
532*e5436536SAndroid Build Coastguard Worker         goto bail;
533*e5436536SAndroid Build Coastguard Worker       }
534*e5436536SAndroid Build Coastguard Worker     }
535*e5436536SAndroid Build Coastguard Worker 
536*e5436536SAndroid Build Coastguard Worker     pLatmDemux->m_crcCheckPresent = FDKreadBits(bs, 1);
537*e5436536SAndroid Build Coastguard Worker 
538*e5436536SAndroid Build Coastguard Worker     if (pLatmDemux->m_crcCheckPresent) {
539*e5436536SAndroid Build Coastguard Worker       FDKreadBits(bs, 8);
540*e5436536SAndroid Build Coastguard Worker     }
541*e5436536SAndroid Build Coastguard Worker 
542*e5436536SAndroid Build Coastguard Worker   } else {
543*e5436536SAndroid Build Coastguard Worker     /* audioMuxVersionA > 0 is reserved for future extensions */
544*e5436536SAndroid Build Coastguard Worker     ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
545*e5436536SAndroid Build Coastguard Worker   }
546*e5436536SAndroid Build Coastguard Worker 
547*e5436536SAndroid Build Coastguard Worker   /* Configure source decoder: */
548*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus == TRANSPORTDEC_OK) {
549*e5436536SAndroid Build Coastguard Worker     UINT prog;
550*e5436536SAndroid Build Coastguard Worker     for (prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
551*e5436536SAndroid Build Coastguard Worker       UINT lay;
552*e5436536SAndroid Build Coastguard Worker       for (lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
553*e5436536SAndroid Build Coastguard Worker         if (updateConfig[TPDEC_TRACKINDEX(prog, lay)] != 0) {
554*e5436536SAndroid Build Coastguard Worker           int cbError;
555*e5436536SAndroid Build Coastguard Worker           cbError = pTpDecCallbacks->cbUpdateConfig(
556*e5436536SAndroid Build Coastguard Worker               pTpDecCallbacks->cbUpdateConfigData,
557*e5436536SAndroid Build Coastguard Worker               &pAsc[TPDEC_TRACKINDEX(prog, lay)],
558*e5436536SAndroid Build Coastguard Worker               pAsc[TPDEC_TRACKINDEX(prog, lay)].configMode,
559*e5436536SAndroid Build Coastguard Worker               &pAsc[TPDEC_TRACKINDEX(prog, lay)].AacConfigChanged);
560*e5436536SAndroid Build Coastguard Worker           if (cbError == TRANSPORTDEC_NEED_TO_RESTART) {
561*e5436536SAndroid Build Coastguard Worker             *pfConfigFound = 0;
562*e5436536SAndroid Build Coastguard Worker             ErrorStatus = TRANSPORTDEC_NEED_TO_RESTART;
563*e5436536SAndroid Build Coastguard Worker             goto bail;
564*e5436536SAndroid Build Coastguard Worker           }
565*e5436536SAndroid Build Coastguard Worker           if (cbError != 0) {
566*e5436536SAndroid Build Coastguard Worker             *pfConfigFound = 0;
567*e5436536SAndroid Build Coastguard Worker             if (lay == 0) {
568*e5436536SAndroid Build Coastguard Worker               ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
569*e5436536SAndroid Build Coastguard Worker               goto bail;
570*e5436536SAndroid Build Coastguard Worker             }
571*e5436536SAndroid Build Coastguard Worker           } else {
572*e5436536SAndroid Build Coastguard Worker             *pfConfigFound = 1;
573*e5436536SAndroid Build Coastguard Worker           }
574*e5436536SAndroid Build Coastguard Worker         } else {
575*e5436536SAndroid Build Coastguard Worker           *pfConfigFound = 1;
576*e5436536SAndroid Build Coastguard Worker         }
577*e5436536SAndroid Build Coastguard Worker       }
578*e5436536SAndroid Build Coastguard Worker     }
579*e5436536SAndroid Build Coastguard Worker   }
580*e5436536SAndroid Build Coastguard Worker 
581*e5436536SAndroid Build Coastguard Worker bail:
582*e5436536SAndroid Build Coastguard Worker   if (ErrorStatus != TRANSPORTDEC_OK) {
583*e5436536SAndroid Build Coastguard Worker     UCHAR applyAsc = pLatmDemux->applyAsc;
584*e5436536SAndroid Build Coastguard Worker     FDKmemclear(pLatmDemux, sizeof(CLatmDemux)); /* reset structure */
585*e5436536SAndroid Build Coastguard Worker     pLatmDemux->applyAsc = applyAsc;
586*e5436536SAndroid Build Coastguard Worker   } else {
587*e5436536SAndroid Build Coastguard Worker     /* no error and config parsing is finished */
588*e5436536SAndroid Build Coastguard Worker     if (configMode == AC_CM_ALLOC_MEM) pLatmDemux->applyAsc = 0;
589*e5436536SAndroid Build Coastguard Worker   }
590*e5436536SAndroid Build Coastguard Worker 
591*e5436536SAndroid Build Coastguard Worker   return (ErrorStatus);
592*e5436536SAndroid Build Coastguard Worker }
593*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs)594*e5436536SAndroid Build Coastguard Worker static int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) {
595*e5436536SAndroid Build Coastguard Worker   int len = 0, tmp = 255;
596*e5436536SAndroid Build Coastguard Worker   int validBytes = (int)FDKgetValidBits(bs) >> 3;
597*e5436536SAndroid Build Coastguard Worker 
598*e5436536SAndroid Build Coastguard Worker   while (tmp == 255 && validBytes-- > 0) {
599*e5436536SAndroid Build Coastguard Worker     tmp = (int)FDKreadBits(bs, 8);
600*e5436536SAndroid Build Coastguard Worker     len += tmp;
601*e5436536SAndroid Build Coastguard Worker   }
602*e5436536SAndroid Build Coastguard Worker 
603*e5436536SAndroid Build Coastguard Worker   return ((tmp == 255) ? -1 : (len << 3));
604*e5436536SAndroid Build Coastguard Worker }
605*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,CLatmDemux * pLatmDemux)606*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
607*e5436536SAndroid Build Coastguard Worker                                                     CLatmDemux *pLatmDemux) {
608*e5436536SAndroid Build Coastguard Worker   TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
609*e5436536SAndroid Build Coastguard Worker   int totalPayloadBits = 0;
610*e5436536SAndroid Build Coastguard Worker 
611*e5436536SAndroid Build Coastguard Worker   if (pLatmDemux->m_allStreamsSameTimeFraming == 1) {
612*e5436536SAndroid Build Coastguard Worker     FDK_ASSERT(pLatmDemux->m_numProgram <= LATM_MAX_PROG);
613*e5436536SAndroid Build Coastguard Worker     for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
614*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER);
615*e5436536SAndroid Build Coastguard Worker       for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
616*e5436536SAndroid Build Coastguard Worker         LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay];
617*e5436536SAndroid Build Coastguard Worker         int auChunkLengthInfo = 0;
618*e5436536SAndroid Build Coastguard Worker 
619*e5436536SAndroid Build Coastguard Worker         switch (p_linfo->m_frameLengthType) {
620*e5436536SAndroid Build Coastguard Worker           case 0:
621*e5436536SAndroid Build Coastguard Worker             auChunkLengthInfo = CLatmDemux_ReadAuChunkLengthInfo(bs);
622*e5436536SAndroid Build Coastguard Worker             if (auChunkLengthInfo >= 0) {
623*e5436536SAndroid Build Coastguard Worker               p_linfo->m_frameLengthInBits = (UINT)auChunkLengthInfo;
624*e5436536SAndroid Build Coastguard Worker               totalPayloadBits += p_linfo->m_frameLengthInBits;
625*e5436536SAndroid Build Coastguard Worker             } else {
626*e5436536SAndroid Build Coastguard Worker               return TRANSPORTDEC_PARSE_ERROR;
627*e5436536SAndroid Build Coastguard Worker             }
628*e5436536SAndroid Build Coastguard Worker             break;
629*e5436536SAndroid Build Coastguard Worker           case 3:
630*e5436536SAndroid Build Coastguard Worker           case 5:
631*e5436536SAndroid Build Coastguard Worker           case 7:
632*e5436536SAndroid Build Coastguard Worker           default:
633*e5436536SAndroid Build Coastguard Worker             return TRANSPORTDEC_PARSE_ERROR;  // AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE;
634*e5436536SAndroid Build Coastguard Worker         }
635*e5436536SAndroid Build Coastguard Worker       }
636*e5436536SAndroid Build Coastguard Worker     }
637*e5436536SAndroid Build Coastguard Worker   } else {
638*e5436536SAndroid Build Coastguard Worker     ErrorStatus = TRANSPORTDEC_PARSE_ERROR;  // AAC_DEC_LATM_TIMEFRAMING;
639*e5436536SAndroid Build Coastguard Worker   }
640*e5436536SAndroid Build Coastguard Worker   if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 &&
641*e5436536SAndroid Build Coastguard Worker       totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes * 8) {
642*e5436536SAndroid Build Coastguard Worker     return TRANSPORTDEC_PARSE_ERROR;
643*e5436536SAndroid Build Coastguard Worker   }
644*e5436536SAndroid Build Coastguard Worker 
645*e5436536SAndroid Build Coastguard Worker   return (ErrorStatus);
646*e5436536SAndroid Build Coastguard Worker }
647*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_GetFrameLengthInBits(CLatmDemux * pLatmDemux,const UINT prog,const UINT layer)648*e5436536SAndroid Build Coastguard Worker UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog,
649*e5436536SAndroid Build Coastguard Worker                                      const UINT layer) {
650*e5436536SAndroid Build Coastguard Worker   UINT nFrameLenBits = 0;
651*e5436536SAndroid Build Coastguard Worker   if (prog < pLatmDemux->m_numProgram) {
652*e5436536SAndroid Build Coastguard Worker     if (layer < pLatmDemux->m_numLayer[prog]) {
653*e5436536SAndroid Build Coastguard Worker       nFrameLenBits = pLatmDemux->m_linfo[prog][layer].m_frameLengthInBits;
654*e5436536SAndroid Build Coastguard Worker     }
655*e5436536SAndroid Build Coastguard Worker   }
656*e5436536SAndroid Build Coastguard Worker   return nFrameLenBits;
657*e5436536SAndroid Build Coastguard Worker }
658*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_GetOtherDataPresentFlag(CLatmDemux * pLatmDemux)659*e5436536SAndroid Build Coastguard Worker UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) {
660*e5436536SAndroid Build Coastguard Worker   return pLatmDemux->m_otherDataPresent ? 1 : 0;
661*e5436536SAndroid Build Coastguard Worker }
662*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_GetOtherDataLength(CLatmDemux * pLatmDemux)663*e5436536SAndroid Build Coastguard Worker UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) {
664*e5436536SAndroid Build Coastguard Worker   return pLatmDemux->m_otherDataLength;
665*e5436536SAndroid Build Coastguard Worker }
666*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_GetNrOfSubFrames(CLatmDemux * pLatmDemux)667*e5436536SAndroid Build Coastguard Worker UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) {
668*e5436536SAndroid Build Coastguard Worker   return pLatmDemux->m_noSubFrames;
669*e5436536SAndroid Build Coastguard Worker }
670*e5436536SAndroid Build Coastguard Worker 
CLatmDemux_GetNrOfLayers(CLatmDemux * pLatmDemux,const UINT prog)671*e5436536SAndroid Build Coastguard Worker UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT prog) {
672*e5436536SAndroid Build Coastguard Worker   UINT numLayer = 0;
673*e5436536SAndroid Build Coastguard Worker   if (prog < pLatmDemux->m_numProgram) {
674*e5436536SAndroid Build Coastguard Worker     numLayer = pLatmDemux->m_numLayer[prog];
675*e5436536SAndroid Build Coastguard Worker   }
676*e5436536SAndroid Build Coastguard Worker   return numLayer;
677*e5436536SAndroid Build Coastguard Worker }
678