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 - 2022 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): Manuel Jander
98*e5436536SAndroid Build Coastguard Worker
99*e5436536SAndroid Build Coastguard Worker Description: MPEG Transport decoder
100*e5436536SAndroid Build Coastguard Worker
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker
103*e5436536SAndroid Build Coastguard Worker #include "tpdec_lib.h"
104*e5436536SAndroid Build Coastguard Worker
105*e5436536SAndroid Build Coastguard Worker /* library version */
106*e5436536SAndroid Build Coastguard Worker #include "tp_version.h"
107*e5436536SAndroid Build Coastguard Worker
108*e5436536SAndroid Build Coastguard Worker #include "tp_data.h"
109*e5436536SAndroid Build Coastguard Worker
110*e5436536SAndroid Build Coastguard Worker #include "tpdec_adts.h"
111*e5436536SAndroid Build Coastguard Worker
112*e5436536SAndroid Build Coastguard Worker #include "tpdec_adif.h"
113*e5436536SAndroid Build Coastguard Worker
114*e5436536SAndroid Build Coastguard Worker #include "tpdec_latm.h"
115*e5436536SAndroid Build Coastguard Worker
116*e5436536SAndroid Build Coastguard Worker #include "tpdec_drm.h"
117*e5436536SAndroid Build Coastguard Worker
118*e5436536SAndroid Build Coastguard Worker #include "FDK_crc.h"
119*e5436536SAndroid Build Coastguard Worker
120*e5436536SAndroid Build Coastguard Worker #define MODULE_NAME "transportDec"
121*e5436536SAndroid Build Coastguard Worker
122*e5436536SAndroid Build Coastguard Worker typedef union {
123*e5436536SAndroid Build Coastguard Worker STRUCT_ADTS adts;
124*e5436536SAndroid Build Coastguard Worker
125*e5436536SAndroid Build Coastguard Worker CAdifHeader adif;
126*e5436536SAndroid Build Coastguard Worker
127*e5436536SAndroid Build Coastguard Worker CLatmDemux latm;
128*e5436536SAndroid Build Coastguard Worker
129*e5436536SAndroid Build Coastguard Worker STRUCT_DRM drm;
130*e5436536SAndroid Build Coastguard Worker
131*e5436536SAndroid Build Coastguard Worker } transportdec_parser_t;
132*e5436536SAndroid Build Coastguard Worker
133*e5436536SAndroid Build Coastguard Worker #define MHAS_CONFIG_PRESENT 0x001
134*e5436536SAndroid Build Coastguard Worker #define MHAS_UI_PRESENT 0x002
135*e5436536SAndroid Build Coastguard Worker
136*e5436536SAndroid Build Coastguard Worker struct TRANSPORTDEC {
137*e5436536SAndroid Build Coastguard Worker TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */
138*e5436536SAndroid Build Coastguard Worker
139*e5436536SAndroid Build Coastguard Worker CSTpCallBacks callbacks; /*!< Struct holding callback and its data */
140*e5436536SAndroid Build Coastguard Worker
141*e5436536SAndroid Build Coastguard Worker FDK_BITSTREAM bitStream[1]; /* Bitstream reader */
142*e5436536SAndroid Build Coastguard Worker UCHAR *bsBuffer; /* Internal bitstreamd data buffer */
143*e5436536SAndroid Build Coastguard Worker
144*e5436536SAndroid Build Coastguard Worker transportdec_parser_t parser; /* Format specific parser structs. */
145*e5436536SAndroid Build Coastguard Worker
146*e5436536SAndroid Build Coastguard Worker CSAudioSpecificConfig asc[(1 * 1) + 1]; /* Audio specific config from the last
147*e5436536SAndroid Build Coastguard Worker config found. One additional
148*e5436536SAndroid Build Coastguard Worker CSAudioSpecificConfig is used
149*e5436536SAndroid Build Coastguard Worker temporarily for parsing. */
150*e5436536SAndroid Build Coastguard Worker CCtrlCFGChange ctrlCFGChange[(1 * 1)]; /* Controls config change */
151*e5436536SAndroid Build Coastguard Worker
152*e5436536SAndroid Build Coastguard Worker UINT globalFramePos; /* Global transport frame reference bit position. */
153*e5436536SAndroid Build Coastguard Worker UINT accessUnitAnchor[1]; /* Current access unit start bit position. */
154*e5436536SAndroid Build Coastguard Worker INT auLength[1]; /* Length of current access unit. */
155*e5436536SAndroid Build Coastguard Worker INT numberOfRawDataBlocks; /* Current number of raw data blocks contained
156*e5436536SAndroid Build Coastguard Worker remaining from the current transport frame. */
157*e5436536SAndroid Build Coastguard Worker UINT avgBitRate; /* Average bit rate used for frame loss estimation. */
158*e5436536SAndroid Build Coastguard Worker UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame
159*e5436536SAndroid Build Coastguard Worker loss estimation */
160*e5436536SAndroid Build Coastguard Worker INT remainder; /* Reminder in division during lost access unit estimation. */
161*e5436536SAndroid Build Coastguard Worker INT missingAccessUnits; /* Estimated missing access units. */
162*e5436536SAndroid Build Coastguard Worker UINT burstPeriod; /* Data burst period in mili seconds. */
163*e5436536SAndroid Build Coastguard Worker UINT holdOffFrames; /* Amount of frames that were already hold off due to
164*e5436536SAndroid Build Coastguard Worker buffer fullness condition not being met. */
165*e5436536SAndroid Build Coastguard Worker UINT flags; /* Flags. */
166*e5436536SAndroid Build Coastguard Worker INT targetLayout; /* CICP target layout. */
167*e5436536SAndroid Build Coastguard Worker UINT *pLoudnessInfoSetPosition; /* Reference and start position (bits) and
168*e5436536SAndroid Build Coastguard Worker length (bytes) of loudnessInfoSet within
169*e5436536SAndroid Build Coastguard Worker rsv603daConfig. */
170*e5436536SAndroid Build Coastguard Worker };
171*e5436536SAndroid Build Coastguard Worker
172*e5436536SAndroid Build Coastguard Worker /* Flag bitmasks for "flags" member of struct TRANSPORTDEC */
173*e5436536SAndroid Build Coastguard Worker #define TPDEC_SYNCOK 1
174*e5436536SAndroid Build Coastguard Worker #define TPDEC_MINIMIZE_DELAY 2
175*e5436536SAndroid Build Coastguard Worker #define TPDEC_IGNORE_BUFFERFULLNESS 4
176*e5436536SAndroid Build Coastguard Worker #define TPDEC_EARLY_CONFIG 8
177*e5436536SAndroid Build Coastguard Worker #define TPDEC_LOST_FRAMES_PENDING 16
178*e5436536SAndroid Build Coastguard Worker #define TPDEC_CONFIG_FOUND 32
179*e5436536SAndroid Build Coastguard Worker #define TPDEC_USE_ELEM_SKIPPING 64
180*e5436536SAndroid Build Coastguard Worker
181*e5436536SAndroid Build Coastguard Worker /* force config/content change */
182*e5436536SAndroid Build Coastguard Worker #define TPDEC_FORCE_CONFIG_CHANGE 1
183*e5436536SAndroid Build Coastguard Worker #define TPDEC_FORCE_CONTENT_CHANGE 2
184*e5436536SAndroid Build Coastguard Worker
185*e5436536SAndroid Build Coastguard Worker /* skip packet */
186*e5436536SAndroid Build Coastguard Worker #define TPDEC_SKIP_PACKET 1
187*e5436536SAndroid Build Coastguard Worker
188*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM(Ram_TransportDecoder, struct TRANSPORTDEC, 1)
189*e5436536SAndroid Build Coastguard Worker C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, (8192 * 4))
190*e5436536SAndroid Build Coastguard Worker
transportDec_Open(const TRANSPORT_TYPE transportFmt,const UINT flags,const UINT nrOfLayers)191*e5436536SAndroid Build Coastguard Worker HANDLE_TRANSPORTDEC transportDec_Open(const TRANSPORT_TYPE transportFmt,
192*e5436536SAndroid Build Coastguard Worker const UINT flags, const UINT nrOfLayers) {
193*e5436536SAndroid Build Coastguard Worker HANDLE_TRANSPORTDEC hInput;
194*e5436536SAndroid Build Coastguard Worker
195*e5436536SAndroid Build Coastguard Worker hInput = GetRam_TransportDecoder(0);
196*e5436536SAndroid Build Coastguard Worker if (hInput == NULL) {
197*e5436536SAndroid Build Coastguard Worker return NULL;
198*e5436536SAndroid Build Coastguard Worker }
199*e5436536SAndroid Build Coastguard Worker
200*e5436536SAndroid Build Coastguard Worker /* Init transportDec struct. */
201*e5436536SAndroid Build Coastguard Worker hInput->transportFmt = transportFmt;
202*e5436536SAndroid Build Coastguard Worker
203*e5436536SAndroid Build Coastguard Worker switch (transportFmt) {
204*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADIF:
205*e5436536SAndroid Build Coastguard Worker break;
206*e5436536SAndroid Build Coastguard Worker
207*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
208*e5436536SAndroid Build Coastguard Worker if (flags & TP_FLAG_MPEG4)
209*e5436536SAndroid Build Coastguard Worker hInput->parser.adts.decoderCanDoMpeg4 = 1;
210*e5436536SAndroid Build Coastguard Worker else
211*e5436536SAndroid Build Coastguard Worker hInput->parser.adts.decoderCanDoMpeg4 = 0;
212*e5436536SAndroid Build Coastguard Worker adtsRead_CrcInit(&hInput->parser.adts);
213*e5436536SAndroid Build Coastguard Worker hInput->parser.adts.BufferFullnesStartFlag = 1;
214*e5436536SAndroid Build Coastguard Worker hInput->numberOfRawDataBlocks = 0;
215*e5436536SAndroid Build Coastguard Worker break;
216*e5436536SAndroid Build Coastguard Worker
217*e5436536SAndroid Build Coastguard Worker case TT_DRM:
218*e5436536SAndroid Build Coastguard Worker drmRead_CrcInit(&hInput->parser.drm);
219*e5436536SAndroid Build Coastguard Worker break;
220*e5436536SAndroid Build Coastguard Worker
221*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
222*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1:
223*e5436536SAndroid Build Coastguard Worker hInput->parser.latm.usacExplicitCfgChanged = 0;
224*e5436536SAndroid Build Coastguard Worker hInput->parser.latm.applyAsc = 1;
225*e5436536SAndroid Build Coastguard Worker break;
226*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
227*e5436536SAndroid Build Coastguard Worker hInput->parser.latm.usacExplicitCfgChanged = 0;
228*e5436536SAndroid Build Coastguard Worker hInput->parser.latm.applyAsc = 1;
229*e5436536SAndroid Build Coastguard Worker break;
230*e5436536SAndroid Build Coastguard Worker case TT_MP4_RAW:
231*e5436536SAndroid Build Coastguard Worker break;
232*e5436536SAndroid Build Coastguard Worker
233*e5436536SAndroid Build Coastguard Worker default:
234*e5436536SAndroid Build Coastguard Worker FreeRam_TransportDecoder(&hInput);
235*e5436536SAndroid Build Coastguard Worker hInput = NULL;
236*e5436536SAndroid Build Coastguard Worker break;
237*e5436536SAndroid Build Coastguard Worker }
238*e5436536SAndroid Build Coastguard Worker
239*e5436536SAndroid Build Coastguard Worker if (hInput != NULL) {
240*e5436536SAndroid Build Coastguard Worker /* Create bitstream */
241*e5436536SAndroid Build Coastguard Worker {
242*e5436536SAndroid Build Coastguard Worker hInput->bsBuffer = GetRam_TransportDecoderBuffer(0);
243*e5436536SAndroid Build Coastguard Worker if (hInput->bsBuffer == NULL) {
244*e5436536SAndroid Build Coastguard Worker transportDec_Close(&hInput);
245*e5436536SAndroid Build Coastguard Worker return NULL;
246*e5436536SAndroid Build Coastguard Worker }
247*e5436536SAndroid Build Coastguard Worker if (nrOfLayers > 1) {
248*e5436536SAndroid Build Coastguard Worker transportDec_Close(&hInput);
249*e5436536SAndroid Build Coastguard Worker return NULL;
250*e5436536SAndroid Build Coastguard Worker }
251*e5436536SAndroid Build Coastguard Worker for (UINT i = 0; i < nrOfLayers; i++) {
252*e5436536SAndroid Build Coastguard Worker FDKinitBitStream(&hInput->bitStream[i], hInput->bsBuffer, (8192 * 4), 0,
253*e5436536SAndroid Build Coastguard Worker BS_READER);
254*e5436536SAndroid Build Coastguard Worker }
255*e5436536SAndroid Build Coastguard Worker }
256*e5436536SAndroid Build Coastguard Worker hInput->burstPeriod = 0;
257*e5436536SAndroid Build Coastguard Worker }
258*e5436536SAndroid Build Coastguard Worker
259*e5436536SAndroid Build Coastguard Worker return hInput;
260*e5436536SAndroid Build Coastguard Worker }
261*e5436536SAndroid Build Coastguard Worker
transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,UCHAR * conf,const UINT length,UINT layer)262*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,
263*e5436536SAndroid Build Coastguard Worker UCHAR *conf, const UINT length,
264*e5436536SAndroid Build Coastguard Worker UINT layer) {
265*e5436536SAndroid Build Coastguard Worker int i;
266*e5436536SAndroid Build Coastguard Worker
267*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
268*e5436536SAndroid Build Coastguard Worker
269*e5436536SAndroid Build Coastguard Worker FDK_BITSTREAM bs;
270*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs = &bs;
271*e5436536SAndroid Build Coastguard Worker
272*e5436536SAndroid Build Coastguard Worker int fConfigFound = 0;
273*e5436536SAndroid Build Coastguard Worker
274*e5436536SAndroid Build Coastguard Worker UCHAR configChanged = 0;
275*e5436536SAndroid Build Coastguard Worker UCHAR configMode = AC_CM_DET_CFG_CHANGE;
276*e5436536SAndroid Build Coastguard Worker
277*e5436536SAndroid Build Coastguard Worker UCHAR tmpConf[1024] = {0};
278*e5436536SAndroid Build Coastguard Worker if (length > 1024) {
279*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_UNSUPPORTED_FORMAT;
280*e5436536SAndroid Build Coastguard Worker }
281*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tmpConf, conf, length);
282*e5436536SAndroid Build Coastguard Worker FDKinitBitStream(hBs, tmpConf, 1024, length << 3, BS_READER);
283*e5436536SAndroid Build Coastguard Worker
284*e5436536SAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
285*e5436536SAndroid Build Coastguard Worker if (i > 0) {
286*e5436536SAndroid Build Coastguard Worker FDKpushBack(hBs, (INT)length * 8 - (INT)FDKgetValidBits(hBs));
287*e5436536SAndroid Build Coastguard Worker configMode = AC_CM_ALLOC_MEM;
288*e5436536SAndroid Build Coastguard Worker }
289*e5436536SAndroid Build Coastguard Worker
290*e5436536SAndroid Build Coastguard Worker /* config transport decoder */
291*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
292*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
293*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1:
294*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS: {
295*e5436536SAndroid Build Coastguard Worker if (layer != 0) {
296*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_INVALID_PARAMETER;
297*e5436536SAndroid Build Coastguard Worker }
298*e5436536SAndroid Build Coastguard Worker CLatmDemux *pLatmDemux = &hTp->parser.latm;
299*e5436536SAndroid Build Coastguard Worker err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks,
300*e5436536SAndroid Build Coastguard Worker hTp->asc, &fConfigFound,
301*e5436536SAndroid Build Coastguard Worker configMode, configChanged);
302*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_OK) {
303*e5436536SAndroid Build Coastguard Worker return err;
304*e5436536SAndroid Build Coastguard Worker }
305*e5436536SAndroid Build Coastguard Worker } break;
306*e5436536SAndroid Build Coastguard Worker default:
307*e5436536SAndroid Build Coastguard Worker fConfigFound = 1;
308*e5436536SAndroid Build Coastguard Worker err = AudioSpecificConfig_Parse(&hTp->asc[(1 * 1)], hBs, 1,
309*e5436536SAndroid Build Coastguard Worker &hTp->callbacks, configMode,
310*e5436536SAndroid Build Coastguard Worker configChanged, AOT_NULL_OBJECT);
311*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
312*e5436536SAndroid Build Coastguard Worker int errC;
313*e5436536SAndroid Build Coastguard Worker
314*e5436536SAndroid Build Coastguard Worker hTp->asc[layer] = hTp->asc[(1 * 1)];
315*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbUpdateConfig(
316*e5436536SAndroid Build Coastguard Worker hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
317*e5436536SAndroid Build Coastguard Worker hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
318*e5436536SAndroid Build Coastguard Worker if (errC != 0) {
319*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
320*e5436536SAndroid Build Coastguard Worker }
321*e5436536SAndroid Build Coastguard Worker }
322*e5436536SAndroid Build Coastguard Worker break;
323*e5436536SAndroid Build Coastguard Worker case TT_DRM:
324*e5436536SAndroid Build Coastguard Worker fConfigFound = 1;
325*e5436536SAndroid Build Coastguard Worker err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs, &hTp->callbacks,
326*e5436536SAndroid Build Coastguard Worker configMode, configChanged);
327*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
328*e5436536SAndroid Build Coastguard Worker int errC;
329*e5436536SAndroid Build Coastguard Worker
330*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbUpdateConfig(
331*e5436536SAndroid Build Coastguard Worker hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
332*e5436536SAndroid Build Coastguard Worker hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
333*e5436536SAndroid Build Coastguard Worker if (errC != 0) {
334*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
335*e5436536SAndroid Build Coastguard Worker }
336*e5436536SAndroid Build Coastguard Worker }
337*e5436536SAndroid Build Coastguard Worker break;
338*e5436536SAndroid Build Coastguard Worker }
339*e5436536SAndroid Build Coastguard Worker
340*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
341*e5436536SAndroid Build Coastguard Worker if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
342*e5436536SAndroid Build Coastguard Worker hTp->asc[layer].SbrConfigChanged ||
343*e5436536SAndroid Build Coastguard Worker hTp->asc[layer].SacConfigChanged)) {
344*e5436536SAndroid Build Coastguard Worker int errC;
345*e5436536SAndroid Build Coastguard Worker
346*e5436536SAndroid Build Coastguard Worker configChanged = 1;
347*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
348*e5436536SAndroid Build Coastguard Worker &hTp->asc[layer]);
349*e5436536SAndroid Build Coastguard Worker if (errC != 0) {
350*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
351*e5436536SAndroid Build Coastguard Worker }
352*e5436536SAndroid Build Coastguard Worker }
353*e5436536SAndroid Build Coastguard Worker }
354*e5436536SAndroid Build Coastguard Worker
355*e5436536SAndroid Build Coastguard Worker /* if an error is detected terminate config parsing to avoid that an invalid
356*e5436536SAndroid Build Coastguard Worker * config is accepted in the second pass */
357*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_OK) {
358*e5436536SAndroid Build Coastguard Worker break;
359*e5436536SAndroid Build Coastguard Worker }
360*e5436536SAndroid Build Coastguard Worker }
361*e5436536SAndroid Build Coastguard Worker
362*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK && fConfigFound) {
363*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_CONFIG_FOUND;
364*e5436536SAndroid Build Coastguard Worker }
365*e5436536SAndroid Build Coastguard Worker
366*e5436536SAndroid Build Coastguard Worker return err;
367*e5436536SAndroid Build Coastguard Worker }
368*e5436536SAndroid Build Coastguard Worker
transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,UCHAR * newConfig,const UINT newConfigLength,const UCHAR buildUpStatus,UCHAR * configChanged,UINT layer,UCHAR * implicitExplicitCfgDiff)369*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
370*e5436536SAndroid Build Coastguard Worker UCHAR *newConfig,
371*e5436536SAndroid Build Coastguard Worker const UINT newConfigLength,
372*e5436536SAndroid Build Coastguard Worker const UCHAR buildUpStatus,
373*e5436536SAndroid Build Coastguard Worker UCHAR *configChanged, UINT layer,
374*e5436536SAndroid Build Coastguard Worker UCHAR *implicitExplicitCfgDiff) {
375*e5436536SAndroid Build Coastguard Worker int errC;
376*e5436536SAndroid Build Coastguard Worker FDK_BITSTREAM bs;
377*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs = &bs;
378*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
379*e5436536SAndroid Build Coastguard Worker int fConfigFound = 0;
380*e5436536SAndroid Build Coastguard Worker UCHAR configMode = AC_CM_ALLOC_MEM;
381*e5436536SAndroid Build Coastguard Worker *implicitExplicitCfgDiff = 0;
382*e5436536SAndroid Build Coastguard Worker
383*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(hTp->asc->m_aot == AOT_USAC);
384*e5436536SAndroid Build Coastguard Worker
385*e5436536SAndroid Build Coastguard Worker FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3,
386*e5436536SAndroid Build Coastguard Worker BS_READER);
387*e5436536SAndroid Build Coastguard Worker
388*e5436536SAndroid Build Coastguard Worker if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
389*e5436536SAndroid Build Coastguard Worker (hTp->ctrlCFGChange[layer].buildUpStatus !=
390*e5436536SAndroid Build Coastguard Worker TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
391*e5436536SAndroid Build Coastguard Worker if (hTp->asc->m_aot == AOT_USAC) {
392*e5436536SAndroid Build Coastguard Worker if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 ==
393*e5436536SAndroid Build Coastguard Worker newConfigLength) {
394*e5436536SAndroid Build Coastguard Worker if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig,
395*e5436536SAndroid Build Coastguard Worker newConfigLength)) {
396*e5436536SAndroid Build Coastguard Worker if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from
397*e5436536SAndroid Build Coastguard Worker LOAS/LATM parser */
398*e5436536SAndroid Build Coastguard Worker hTp->parser.latm.usacExplicitCfgChanged = 0;
399*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushCnt = 0;
400*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushStatus =
401*e5436536SAndroid Build Coastguard Worker TPDEC_USAC_DASH_IPF_FLUSH_ON;
402*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpCnt = 0;
403*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
404*e5436536SAndroid Build Coastguard Worker } else {
405*e5436536SAndroid Build Coastguard Worker *configChanged = 0;
406*e5436536SAndroid Build Coastguard Worker return err;
407*e5436536SAndroid Build Coastguard Worker }
408*e5436536SAndroid Build Coastguard Worker } else {
409*e5436536SAndroid Build Coastguard Worker *implicitExplicitCfgDiff = 1;
410*e5436536SAndroid Build Coastguard Worker }
411*e5436536SAndroid Build Coastguard Worker } else {
412*e5436536SAndroid Build Coastguard Worker *implicitExplicitCfgDiff = 1;
413*e5436536SAndroid Build Coastguard Worker }
414*e5436536SAndroid Build Coastguard Worker /* ISO/IEC 23003-3:2012/FDAM 3:2016(E) Annex F.2: explicit and implicit
415*e5436536SAndroid Build Coastguard Worker * config shall be identical. */
416*e5436536SAndroid Build Coastguard Worker if (*implicitExplicitCfgDiff) {
417*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
418*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
419*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1:
420*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
421*e5436536SAndroid Build Coastguard Worker /* reset decoder to initial state to achieve definite behavior after
422*e5436536SAndroid Build Coastguard Worker * error in config */
423*e5436536SAndroid Build Coastguard Worker hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
424*e5436536SAndroid Build Coastguard Worker &hTp->asc[layer]);
425*e5436536SAndroid Build Coastguard Worker hTp->parser.latm.usacExplicitCfgChanged = 0;
426*e5436536SAndroid Build Coastguard Worker hTp->parser.latm.applyAsc = 1;
427*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
428*e5436536SAndroid Build Coastguard Worker goto bail;
429*e5436536SAndroid Build Coastguard Worker default:
430*e5436536SAndroid Build Coastguard Worker break;
431*e5436536SAndroid Build Coastguard Worker }
432*e5436536SAndroid Build Coastguard Worker }
433*e5436536SAndroid Build Coastguard Worker }
434*e5436536SAndroid Build Coastguard Worker }
435*e5436536SAndroid Build Coastguard Worker
436*e5436536SAndroid Build Coastguard Worker {
437*e5436536SAndroid Build Coastguard Worker if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
438*e5436536SAndroid Build Coastguard Worker (hTp->ctrlCFGChange[layer].buildUpStatus !=
439*e5436536SAndroid Build Coastguard Worker TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
440*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushCnt = 0;
441*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpCnt = 0;
442*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
443*e5436536SAndroid Build Coastguard Worker if (hTp->asc->m_aot == AOT_USAC) {
444*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushStatus = TPDEC_USAC_DASH_IPF_FLUSH_ON;
445*e5436536SAndroid Build Coastguard Worker }
446*e5436536SAndroid Build Coastguard Worker }
447*e5436536SAndroid Build Coastguard Worker
448*e5436536SAndroid Build Coastguard Worker if ((hTp->ctrlCFGChange[layer].flushStatus ==
449*e5436536SAndroid Build Coastguard Worker TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
450*e5436536SAndroid Build Coastguard Worker (hTp->ctrlCFGChange[layer].flushStatus ==
451*e5436536SAndroid Build Coastguard Worker TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
452*e5436536SAndroid Build Coastguard Worker SCHAR counter = 0;
453*e5436536SAndroid Build Coastguard Worker if (hTp->asc->m_aot == AOT_USAC) {
454*e5436536SAndroid Build Coastguard Worker counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES;
455*e5436536SAndroid Build Coastguard Worker }
456*e5436536SAndroid Build Coastguard Worker if (hTp->ctrlCFGChange[layer].flushCnt >= counter) {
457*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushCnt = 0;
458*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
459*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].forceCfgChange = 0;
460*e5436536SAndroid Build Coastguard Worker if (hTp->asc->m_aot == AOT_USAC) {
461*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpCnt =
462*e5436536SAndroid Build Coastguard Worker TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1;
463*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON;
464*e5436536SAndroid Build Coastguard Worker }
465*e5436536SAndroid Build Coastguard Worker }
466*e5436536SAndroid Build Coastguard Worker
467*e5436536SAndroid Build Coastguard Worker /* Activate flush mode. After that continue with build up mode in core */
468*e5436536SAndroid Build Coastguard Worker if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
469*e5436536SAndroid Build Coastguard Worker &hTp->ctrlCFGChange[layer]) != 0) {
470*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
471*e5436536SAndroid Build Coastguard Worker }
472*e5436536SAndroid Build Coastguard Worker
473*e5436536SAndroid Build Coastguard Worker if ((hTp->ctrlCFGChange[layer].flushStatus ==
474*e5436536SAndroid Build Coastguard Worker TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
475*e5436536SAndroid Build Coastguard Worker (hTp->ctrlCFGChange[layer].flushStatus ==
476*e5436536SAndroid Build Coastguard Worker TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
477*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushCnt++;
478*e5436536SAndroid Build Coastguard Worker return err;
479*e5436536SAndroid Build Coastguard Worker }
480*e5436536SAndroid Build Coastguard Worker }
481*e5436536SAndroid Build Coastguard Worker
482*e5436536SAndroid Build Coastguard Worker if (hTp->asc->m_aot == AOT_USAC) {
483*e5436536SAndroid Build Coastguard Worker fConfigFound = 1;
484*e5436536SAndroid Build Coastguard Worker
485*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
486*e5436536SAndroid Build Coastguard Worker *configChanged = 0;
487*e5436536SAndroid Build Coastguard Worker configMode = AC_CM_DET_CFG_CHANGE;
488*e5436536SAndroid Build Coastguard Worker
489*e5436536SAndroid Build Coastguard Worker for (int i = 0; i < 2; i++) {
490*e5436536SAndroid Build Coastguard Worker if (i > 0) {
491*e5436536SAndroid Build Coastguard Worker FDKpushBack(hBs,
492*e5436536SAndroid Build Coastguard Worker (INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs));
493*e5436536SAndroid Build Coastguard Worker configMode = AC_CM_ALLOC_MEM;
494*e5436536SAndroid Build Coastguard Worker }
495*e5436536SAndroid Build Coastguard Worker /* config transport decoder */
496*e5436536SAndroid Build Coastguard Worker err = AudioSpecificConfig_Parse(
497*e5436536SAndroid Build Coastguard Worker &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode,
498*e5436536SAndroid Build Coastguard Worker *configChanged, hTp->asc[layer].m_aot);
499*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
500*e5436536SAndroid Build Coastguard Worker hTp->asc[layer] = hTp->asc[(1 * 1)];
501*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbUpdateConfig(
502*e5436536SAndroid Build Coastguard Worker hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
503*e5436536SAndroid Build Coastguard Worker hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
504*e5436536SAndroid Build Coastguard Worker if (errC != 0) {
505*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
506*e5436536SAndroid Build Coastguard Worker }
507*e5436536SAndroid Build Coastguard Worker }
508*e5436536SAndroid Build Coastguard Worker
509*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
510*e5436536SAndroid Build Coastguard Worker if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
511*e5436536SAndroid Build Coastguard Worker hTp->asc[layer].SbrConfigChanged ||
512*e5436536SAndroid Build Coastguard Worker hTp->asc[layer].SacConfigChanged)) {
513*e5436536SAndroid Build Coastguard Worker *configChanged = 1;
514*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
515*e5436536SAndroid Build Coastguard Worker &hTp->asc[layer]);
516*e5436536SAndroid Build Coastguard Worker if (errC != 0) {
517*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
518*e5436536SAndroid Build Coastguard Worker }
519*e5436536SAndroid Build Coastguard Worker }
520*e5436536SAndroid Build Coastguard Worker }
521*e5436536SAndroid Build Coastguard Worker
522*e5436536SAndroid Build Coastguard Worker /* if an error is detected terminate config parsing to avoid that an
523*e5436536SAndroid Build Coastguard Worker * invalid config is accepted in the second pass */
524*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_OK) {
525*e5436536SAndroid Build Coastguard Worker break;
526*e5436536SAndroid Build Coastguard Worker }
527*e5436536SAndroid Build Coastguard Worker }
528*e5436536SAndroid Build Coastguard Worker }
529*e5436536SAndroid Build Coastguard Worker }
530*e5436536SAndroid Build Coastguard Worker
531*e5436536SAndroid Build Coastguard Worker bail:
532*e5436536SAndroid Build Coastguard Worker /* save new config */
533*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
534*e5436536SAndroid Build Coastguard Worker if (hTp->asc->m_aot == AOT_USAC) {
535*e5436536SAndroid Build Coastguard Worker hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3;
536*e5436536SAndroid Build Coastguard Worker FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig,
537*e5436536SAndroid Build Coastguard Worker newConfigLength);
538*e5436536SAndroid Build Coastguard Worker /* in case of USAC reset transportDecoder variables here because
539*e5436536SAndroid Build Coastguard Worker * otherwise without IPF they are not reset */
540*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushCnt = 0;
541*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
542*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpCnt = 0;
543*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
544*e5436536SAndroid Build Coastguard Worker }
545*e5436536SAndroid Build Coastguard Worker } else {
546*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = 0;
547*e5436536SAndroid Build Coastguard Worker
548*e5436536SAndroid Build Coastguard Worker /* If parsing error while config found, clear ctrlCFGChange-struct */
549*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushCnt = 0;
550*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
551*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpCnt = 0;
552*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
553*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].cfgChanged = 0;
554*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].contentChanged = 0;
555*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[layer].forceCfgChange = 0;
556*e5436536SAndroid Build Coastguard Worker
557*e5436536SAndroid Build Coastguard Worker hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
558*e5436536SAndroid Build Coastguard Worker &hTp->ctrlCFGChange[layer]);
559*e5436536SAndroid Build Coastguard Worker }
560*e5436536SAndroid Build Coastguard Worker }
561*e5436536SAndroid Build Coastguard Worker
562*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK && fConfigFound) {
563*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_CONFIG_FOUND;
564*e5436536SAndroid Build Coastguard Worker }
565*e5436536SAndroid Build Coastguard Worker
566*e5436536SAndroid Build Coastguard Worker return err;
567*e5436536SAndroid Build Coastguard Worker }
568*e5436536SAndroid Build Coastguard Worker
transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUpdateConfig_t cbUpdateConfig,void * user_data)569*e5436536SAndroid Build Coastguard Worker int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,
570*e5436536SAndroid Build Coastguard Worker const cbUpdateConfig_t cbUpdateConfig,
571*e5436536SAndroid Build Coastguard Worker void *user_data) {
572*e5436536SAndroid Build Coastguard Worker if (hTpDec == NULL) {
573*e5436536SAndroid Build Coastguard Worker return -1;
574*e5436536SAndroid Build Coastguard Worker }
575*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbUpdateConfig = cbUpdateConfig;
576*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbUpdateConfigData = user_data;
577*e5436536SAndroid Build Coastguard Worker return 0;
578*e5436536SAndroid Build Coastguard Worker }
579*e5436536SAndroid Build Coastguard Worker
transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,const cbFreeMem_t cbFreeMem,void * user_data)580*e5436536SAndroid Build Coastguard Worker int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,
581*e5436536SAndroid Build Coastguard Worker const cbFreeMem_t cbFreeMem,
582*e5436536SAndroid Build Coastguard Worker void *user_data) {
583*e5436536SAndroid Build Coastguard Worker if (hTpDec == NULL) {
584*e5436536SAndroid Build Coastguard Worker return -1;
585*e5436536SAndroid Build Coastguard Worker }
586*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbFreeMem = cbFreeMem;
587*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbFreeMemData = user_data;
588*e5436536SAndroid Build Coastguard Worker return 0;
589*e5436536SAndroid Build Coastguard Worker }
590*e5436536SAndroid Build Coastguard Worker
transportDec_RegisterCtrlCFGChangeCallback(HANDLE_TRANSPORTDEC hTpDec,const cbCtrlCFGChange_t cbCtrlCFGChange,void * user_data)591*e5436536SAndroid Build Coastguard Worker int transportDec_RegisterCtrlCFGChangeCallback(
592*e5436536SAndroid Build Coastguard Worker HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange,
593*e5436536SAndroid Build Coastguard Worker void *user_data) {
594*e5436536SAndroid Build Coastguard Worker if (hTpDec == NULL) {
595*e5436536SAndroid Build Coastguard Worker return -1;
596*e5436536SAndroid Build Coastguard Worker }
597*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange;
598*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbCtrlCFGChangeData = user_data;
599*e5436536SAndroid Build Coastguard Worker return 0;
600*e5436536SAndroid Build Coastguard Worker }
601*e5436536SAndroid Build Coastguard Worker
transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,const cbSsc_t cbSsc,void * user_data)602*e5436536SAndroid Build Coastguard Worker int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,
603*e5436536SAndroid Build Coastguard Worker const cbSsc_t cbSsc, void *user_data) {
604*e5436536SAndroid Build Coastguard Worker if (hTpDec == NULL) {
605*e5436536SAndroid Build Coastguard Worker return -1;
606*e5436536SAndroid Build Coastguard Worker }
607*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbSsc = cbSsc;
608*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbSscData = user_data;
609*e5436536SAndroid Build Coastguard Worker return 0;
610*e5436536SAndroid Build Coastguard Worker }
611*e5436536SAndroid Build Coastguard Worker
transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,const cbSbr_t cbSbr,void * user_data)612*e5436536SAndroid Build Coastguard Worker int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
613*e5436536SAndroid Build Coastguard Worker const cbSbr_t cbSbr, void *user_data) {
614*e5436536SAndroid Build Coastguard Worker if (hTpDec == NULL) {
615*e5436536SAndroid Build Coastguard Worker return -1;
616*e5436536SAndroid Build Coastguard Worker }
617*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbSbr = cbSbr;
618*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbSbrData = user_data;
619*e5436536SAndroid Build Coastguard Worker return 0;
620*e5436536SAndroid Build Coastguard Worker }
621*e5436536SAndroid Build Coastguard Worker
transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUsac_t cbUsac,void * user_data)622*e5436536SAndroid Build Coastguard Worker int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
623*e5436536SAndroid Build Coastguard Worker const cbUsac_t cbUsac, void *user_data) {
624*e5436536SAndroid Build Coastguard Worker if (hTpDec == NULL) {
625*e5436536SAndroid Build Coastguard Worker return -1;
626*e5436536SAndroid Build Coastguard Worker }
627*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbUsac = cbUsac;
628*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbUsacData = user_data;
629*e5436536SAndroid Build Coastguard Worker return 0;
630*e5436536SAndroid Build Coastguard Worker }
631*e5436536SAndroid Build Coastguard Worker
transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,const cbUniDrc_t cbUniDrc,void * user_data,UINT * pLoudnessInfoSetPosition)632*e5436536SAndroid Build Coastguard Worker int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
633*e5436536SAndroid Build Coastguard Worker const cbUniDrc_t cbUniDrc,
634*e5436536SAndroid Build Coastguard Worker void *user_data,
635*e5436536SAndroid Build Coastguard Worker UINT *pLoudnessInfoSetPosition) {
636*e5436536SAndroid Build Coastguard Worker if (hTpDec == NULL) {
637*e5436536SAndroid Build Coastguard Worker return -1;
638*e5436536SAndroid Build Coastguard Worker }
639*e5436536SAndroid Build Coastguard Worker
640*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbUniDrc = cbUniDrc;
641*e5436536SAndroid Build Coastguard Worker hTpDec->callbacks.cbUniDrcData = user_data;
642*e5436536SAndroid Build Coastguard Worker
643*e5436536SAndroid Build Coastguard Worker hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition;
644*e5436536SAndroid Build Coastguard Worker return 0;
645*e5436536SAndroid Build Coastguard Worker }
646*e5436536SAndroid Build Coastguard Worker
transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,UCHAR * pBuffer,const UINT bufferSize,UINT * pBytesValid,const INT layer)647*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
648*e5436536SAndroid Build Coastguard Worker UCHAR *pBuffer, const UINT bufferSize,
649*e5436536SAndroid Build Coastguard Worker UINT *pBytesValid, const INT layer) {
650*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs;
651*e5436536SAndroid Build Coastguard Worker
652*e5436536SAndroid Build Coastguard Worker if ((hTp == NULL) || (layer >= 1)) {
653*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_INVALID_PARAMETER;
654*e5436536SAndroid Build Coastguard Worker }
655*e5436536SAndroid Build Coastguard Worker
656*e5436536SAndroid Build Coastguard Worker /* set bitbuffer shortcut */
657*e5436536SAndroid Build Coastguard Worker hBs = &hTp->bitStream[layer];
658*e5436536SAndroid Build Coastguard Worker
659*e5436536SAndroid Build Coastguard Worker if (TT_IS_PACKET(hTp->transportFmt)) {
660*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks == 0) {
661*e5436536SAndroid Build Coastguard Worker FDKresetBitbuffer(hBs);
662*e5436536SAndroid Build Coastguard Worker FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
663*e5436536SAndroid Build Coastguard Worker if (*pBytesValid != 0) {
664*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_TOO_MANY_BITS;
665*e5436536SAndroid Build Coastguard Worker }
666*e5436536SAndroid Build Coastguard Worker }
667*e5436536SAndroid Build Coastguard Worker } else {
668*e5436536SAndroid Build Coastguard Worker /* ... else feed bitbuffer with new stream data (append). */
669*e5436536SAndroid Build Coastguard Worker
670*e5436536SAndroid Build Coastguard Worker if (*pBytesValid == 0) {
671*e5436536SAndroid Build Coastguard Worker /* nothing to do */
672*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_OK;
673*e5436536SAndroid Build Coastguard Worker } else {
674*e5436536SAndroid Build Coastguard Worker const int bytesValid = *pBytesValid;
675*e5436536SAndroid Build Coastguard Worker FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
676*e5436536SAndroid Build Coastguard Worker
677*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks > 0) {
678*e5436536SAndroid Build Coastguard Worker hTp->globalFramePos += (bytesValid - *pBytesValid) * 8;
679*e5436536SAndroid Build Coastguard Worker hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
680*e5436536SAndroid Build Coastguard Worker }
681*e5436536SAndroid Build Coastguard Worker }
682*e5436536SAndroid Build Coastguard Worker }
683*e5436536SAndroid Build Coastguard Worker
684*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_OK;
685*e5436536SAndroid Build Coastguard Worker }
686*e5436536SAndroid Build Coastguard Worker
transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,const UINT layer)687*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
688*e5436536SAndroid Build Coastguard Worker const UINT layer) {
689*e5436536SAndroid Build Coastguard Worker return &hTp->bitStream[layer];
690*e5436536SAndroid Build Coastguard Worker }
691*e5436536SAndroid Build Coastguard Worker
transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp)692*e5436536SAndroid Build Coastguard Worker TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) {
693*e5436536SAndroid Build Coastguard Worker return hTp->transportFmt;
694*e5436536SAndroid Build Coastguard Worker }
695*e5436536SAndroid Build Coastguard Worker
transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp)696*e5436536SAndroid Build Coastguard Worker INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) {
697*e5436536SAndroid Build Coastguard Worker INT bufferFullness = -1;
698*e5436536SAndroid Build Coastguard Worker
699*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
700*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
701*e5436536SAndroid Build Coastguard Worker if (hTp->parser.adts.bs.adts_fullness != 0x7ff) {
702*e5436536SAndroid Build Coastguard Worker bufferFullness = hTp->parser.adts.bs.frame_length * 8 +
703*e5436536SAndroid Build Coastguard Worker hTp->parser.adts.bs.adts_fullness * 32 *
704*e5436536SAndroid Build Coastguard Worker getNumberOfEffectiveChannels(
705*e5436536SAndroid Build Coastguard Worker hTp->parser.adts.bs.channel_config);
706*e5436536SAndroid Build Coastguard Worker }
707*e5436536SAndroid Build Coastguard Worker break;
708*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
709*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
710*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1:
711*e5436536SAndroid Build Coastguard Worker if (hTp->parser.latm.m_linfo[0][0].m_bufferFullness != 0xff) {
712*e5436536SAndroid Build Coastguard Worker bufferFullness = hTp->parser.latm.m_linfo[0][0].m_bufferFullness;
713*e5436536SAndroid Build Coastguard Worker }
714*e5436536SAndroid Build Coastguard Worker break;
715*e5436536SAndroid Build Coastguard Worker default:
716*e5436536SAndroid Build Coastguard Worker break;
717*e5436536SAndroid Build Coastguard Worker }
718*e5436536SAndroid Build Coastguard Worker
719*e5436536SAndroid Build Coastguard Worker return bufferFullness;
720*e5436536SAndroid Build Coastguard Worker }
721*e5436536SAndroid Build Coastguard Worker
722*e5436536SAndroid Build Coastguard Worker /**
723*e5436536SAndroid Build Coastguard Worker * \brief adjust bit stream position and the end of an access unit.
724*e5436536SAndroid Build Coastguard Worker * \param hTp transport decoder handle.
725*e5436536SAndroid Build Coastguard Worker * \return error code.
726*e5436536SAndroid Build Coastguard Worker */
transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp)727*e5436536SAndroid Build Coastguard Worker static TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(
728*e5436536SAndroid Build Coastguard Worker HANDLE_TRANSPORTDEC hTp) {
729*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
730*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
731*e5436536SAndroid Build Coastguard Worker
732*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
733*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADIF:
734*e5436536SAndroid Build Coastguard Worker /* Do byte align at the end of raw_data_block() because UsacFrame() is not
735*e5436536SAndroid Build Coastguard Worker * byte aligned. */
736*e5436536SAndroid Build Coastguard Worker FDKbyteAlign(hBs, hTp->accessUnitAnchor[0]);
737*e5436536SAndroid Build Coastguard Worker break;
738*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
739*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
740*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1:
741*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks == 0) {
742*e5436536SAndroid Build Coastguard Worker /* Do byte align at the end of AudioMuxElement. */
743*e5436536SAndroid Build Coastguard Worker FDKbyteAlign(hBs, hTp->globalFramePos);
744*e5436536SAndroid Build Coastguard Worker
745*e5436536SAndroid Build Coastguard Worker /* Check global frame length */
746*e5436536SAndroid Build Coastguard Worker if (hTp->transportFmt == TT_MP4_LOAS &&
747*e5436536SAndroid Build Coastguard Worker hTp->parser.latm.m_audioMuxLengthBytes > 0) {
748*e5436536SAndroid Build Coastguard Worker int loasOffset;
749*e5436536SAndroid Build Coastguard Worker
750*e5436536SAndroid Build Coastguard Worker loasOffset = ((INT)hTp->parser.latm.m_audioMuxLengthBytes * 8 +
751*e5436536SAndroid Build Coastguard Worker (INT)FDKgetValidBits(hBs)) -
752*e5436536SAndroid Build Coastguard Worker (INT)hTp->globalFramePos;
753*e5436536SAndroid Build Coastguard Worker if (loasOffset != 0) {
754*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(hBs, loasOffset);
755*e5436536SAndroid Build Coastguard Worker /* For ELD and other payloads there is an unknown amount of padding,
756*e5436536SAndroid Build Coastguard Worker so ignore unread bits, but throw an error only if too many bits
757*e5436536SAndroid Build Coastguard Worker where read. */
758*e5436536SAndroid Build Coastguard Worker if (loasOffset < 0) {
759*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
760*e5436536SAndroid Build Coastguard Worker }
761*e5436536SAndroid Build Coastguard Worker }
762*e5436536SAndroid Build Coastguard Worker }
763*e5436536SAndroid Build Coastguard Worker }
764*e5436536SAndroid Build Coastguard Worker break;
765*e5436536SAndroid Build Coastguard Worker
766*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
767*e5436536SAndroid Build Coastguard Worker if (hTp->parser.adts.bs.protection_absent == 0) {
768*e5436536SAndroid Build Coastguard Worker int offset;
769*e5436536SAndroid Build Coastguard Worker
770*e5436536SAndroid Build Coastguard Worker /* Calculate offset to end of AU */
771*e5436536SAndroid Build Coastguard Worker offset = hTp->parser.adts
772*e5436536SAndroid Build Coastguard Worker .rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks -
773*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks]
774*e5436536SAndroid Build Coastguard Worker << 3;
775*e5436536SAndroid Build Coastguard Worker /* CAUTION: The PCE (if available) is declared to be a part of the
776*e5436536SAndroid Build Coastguard Worker * header! */
777*e5436536SAndroid Build Coastguard Worker offset -= (INT)hTp->accessUnitAnchor[0] - (INT)FDKgetValidBits(hBs) +
778*e5436536SAndroid Build Coastguard Worker 16 + hTp->parser.adts.bs.num_pce_bits;
779*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(hBs, offset);
780*e5436536SAndroid Build Coastguard Worker }
781*e5436536SAndroid Build Coastguard Worker if (hTp->parser.adts.bs.num_raw_blocks > 0 &&
782*e5436536SAndroid Build Coastguard Worker hTp->parser.adts.bs.protection_absent == 0) {
783*e5436536SAndroid Build Coastguard Worker /* Note this CRC read currently happens twice because of
784*e5436536SAndroid Build Coastguard Worker * transportDec_CrcCheck() */
785*e5436536SAndroid Build Coastguard Worker hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
786*e5436536SAndroid Build Coastguard Worker }
787*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks == 0) {
788*e5436536SAndroid Build Coastguard Worker /* Check global frame length */
789*e5436536SAndroid Build Coastguard Worker if (hTp->parser.adts.bs.protection_absent == 0) {
790*e5436536SAndroid Build Coastguard Worker int offset;
791*e5436536SAndroid Build Coastguard Worker
792*e5436536SAndroid Build Coastguard Worker offset = (hTp->parser.adts.bs.frame_length * 8 - ADTS_SYNCLENGTH +
793*e5436536SAndroid Build Coastguard Worker (INT)FDKgetValidBits(hBs)) -
794*e5436536SAndroid Build Coastguard Worker (INT)hTp->globalFramePos;
795*e5436536SAndroid Build Coastguard Worker if (offset != 0) {
796*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(hBs, offset);
797*e5436536SAndroid Build Coastguard Worker }
798*e5436536SAndroid Build Coastguard Worker }
799*e5436536SAndroid Build Coastguard Worker }
800*e5436536SAndroid Build Coastguard Worker break;
801*e5436536SAndroid Build Coastguard Worker
802*e5436536SAndroid Build Coastguard Worker default:
803*e5436536SAndroid Build Coastguard Worker break;
804*e5436536SAndroid Build Coastguard Worker }
805*e5436536SAndroid Build Coastguard Worker
806*e5436536SAndroid Build Coastguard Worker return err;
807*e5436536SAndroid Build Coastguard Worker }
808*e5436536SAndroid Build Coastguard Worker
809*e5436536SAndroid Build Coastguard Worker /**
810*e5436536SAndroid Build Coastguard Worker * \brief Determine additional buffer fullness contraint due to burst data
811*e5436536SAndroid Build Coastguard Worker * reception. The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a
812*e5436536SAndroid Build Coastguard Worker * precondition.
813*e5436536SAndroid Build Coastguard Worker * \param hTp transport decoder handle.
814*e5436536SAndroid Build Coastguard Worker * \param bufferFullness the buffer fullness value of the first frame to be
815*e5436536SAndroid Build Coastguard Worker * decoded.
816*e5436536SAndroid Build Coastguard Worker * \param bitsAvail the amount of available bits at the end of the first frame
817*e5436536SAndroid Build Coastguard Worker * to be decoded.
818*e5436536SAndroid Build Coastguard Worker * \return error code
819*e5436536SAndroid Build Coastguard Worker */
additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,INT bufferFullness,INT bitsAvail)820*e5436536SAndroid Build Coastguard Worker static TRANSPORTDEC_ERROR additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,
821*e5436536SAndroid Build Coastguard Worker INT bufferFullness,
822*e5436536SAndroid Build Coastguard Worker INT bitsAvail) {
823*e5436536SAndroid Build Coastguard Worker INT checkLengthBits, avgBitsPerFrame;
824*e5436536SAndroid Build Coastguard Worker INT maxAU; /* maximum number of frames per Master Frame */
825*e5436536SAndroid Build Coastguard Worker INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
826*e5436536SAndroid Build Coastguard Worker INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;
827*e5436536SAndroid Build Coastguard Worker
828*e5436536SAndroid Build Coastguard Worker if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) {
829*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_OK;
830*e5436536SAndroid Build Coastguard Worker }
831*e5436536SAndroid Build Coastguard Worker if ((samplesPerFrame == 0) || (samplingFrequency == 0)) {
832*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_NOT_ENOUGH_BITS;
833*e5436536SAndroid Build Coastguard Worker }
834*e5436536SAndroid Build Coastguard Worker
835*e5436536SAndroid Build Coastguard Worker /* One Master Frame is sent every hTp->burstPeriod ms */
836*e5436536SAndroid Build Coastguard Worker maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame * 1000 - 1);
837*e5436536SAndroid Build Coastguard Worker maxAU = maxAU / (samplesPerFrame * 1000);
838*e5436536SAndroid Build Coastguard Worker /* Subtract number of frames which were already held off. */
839*e5436536SAndroid Build Coastguard Worker maxAU -= hTp->holdOffFrames;
840*e5436536SAndroid Build Coastguard Worker
841*e5436536SAndroid Build Coastguard Worker avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency - 1);
842*e5436536SAndroid Build Coastguard Worker avgBitsPerFrame = avgBitsPerFrame / samplingFrequency;
843*e5436536SAndroid Build Coastguard Worker
844*e5436536SAndroid Build Coastguard Worker /* Consider worst case of bufferFullness quantization. */
845*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
846*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADIF:
847*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
848*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
849*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
850*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1:
851*e5436536SAndroid Build Coastguard Worker bufferFullness += 31;
852*e5436536SAndroid Build Coastguard Worker break;
853*e5436536SAndroid Build Coastguard Worker default: /* added to avoid compiler warning */
854*e5436536SAndroid Build Coastguard Worker break; /* added to avoid compiler warning */
855*e5436536SAndroid Build Coastguard Worker }
856*e5436536SAndroid Build Coastguard Worker
857*e5436536SAndroid Build Coastguard Worker checkLengthBits = bufferFullness + (maxAU - 1) * avgBitsPerFrame;
858*e5436536SAndroid Build Coastguard Worker
859*e5436536SAndroid Build Coastguard Worker /* Check if buffer is big enough to fullfill buffer fullness condition */
860*e5436536SAndroid Build Coastguard Worker if ((checkLengthBits /*+headerBits*/) > (((8192 * 4) << 3) - 7)) {
861*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_SYNC_ERROR;
862*e5436536SAndroid Build Coastguard Worker }
863*e5436536SAndroid Build Coastguard Worker
864*e5436536SAndroid Build Coastguard Worker if (bitsAvail < checkLengthBits) {
865*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_NOT_ENOUGH_BITS;
866*e5436536SAndroid Build Coastguard Worker } else {
867*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_OK;
868*e5436536SAndroid Build Coastguard Worker }
869*e5436536SAndroid Build Coastguard Worker }
870*e5436536SAndroid Build Coastguard Worker
transportDec_readHeader(HANDLE_TRANSPORTDEC hTp,HANDLE_FDK_BITSTREAM hBs,int syncLength,int ignoreBufferFullness,int * pRawDataBlockLength,int * pfTraverseMoreFrames,int * pSyncLayerFrameBits,int * pfConfigFound,int * pHeaderBits)871*e5436536SAndroid Build Coastguard Worker static TRANSPORTDEC_ERROR transportDec_readHeader(
872*e5436536SAndroid Build Coastguard Worker HANDLE_TRANSPORTDEC hTp, HANDLE_FDK_BITSTREAM hBs, int syncLength,
873*e5436536SAndroid Build Coastguard Worker int ignoreBufferFullness, int *pRawDataBlockLength,
874*e5436536SAndroid Build Coastguard Worker int *pfTraverseMoreFrames, int *pSyncLayerFrameBits, int *pfConfigFound,
875*e5436536SAndroid Build Coastguard Worker int *pHeaderBits) {
876*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
877*e5436536SAndroid Build Coastguard Worker int rawDataBlockLength = *pRawDataBlockLength;
878*e5436536SAndroid Build Coastguard Worker int fTraverseMoreFrames =
879*e5436536SAndroid Build Coastguard Worker (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
880*e5436536SAndroid Build Coastguard Worker int syncLayerFrameBits =
881*e5436536SAndroid Build Coastguard Worker (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
882*e5436536SAndroid Build Coastguard Worker int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
883*e5436536SAndroid Build Coastguard Worker int startPos;
884*e5436536SAndroid Build Coastguard Worker
885*e5436536SAndroid Build Coastguard Worker startPos = (INT)FDKgetValidBits(hBs);
886*e5436536SAndroid Build Coastguard Worker
887*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
888*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
889*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks <= 0) {
890*e5436536SAndroid Build Coastguard Worker int i, errC;
891*e5436536SAndroid Build Coastguard Worker
892*e5436536SAndroid Build Coastguard Worker hTp->globalFramePos = FDKgetValidBits(hBs);
893*e5436536SAndroid Build Coastguard Worker
894*e5436536SAndroid Build Coastguard Worker UCHAR configChanged = 0;
895*e5436536SAndroid Build Coastguard Worker UCHAR configMode = AC_CM_DET_CFG_CHANGE;
896*e5436536SAndroid Build Coastguard Worker
897*e5436536SAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
898*e5436536SAndroid Build Coastguard Worker if (i > 0) {
899*e5436536SAndroid Build Coastguard Worker FDKpushBack(hBs,
900*e5436536SAndroid Build Coastguard Worker (INT)hTp->globalFramePos - (INT)FDKgetValidBits(hBs));
901*e5436536SAndroid Build Coastguard Worker configMode = AC_CM_ALLOC_MEM;
902*e5436536SAndroid Build Coastguard Worker }
903*e5436536SAndroid Build Coastguard Worker
904*e5436536SAndroid Build Coastguard Worker /* Parse ADTS header */
905*e5436536SAndroid Build Coastguard Worker err = adtsRead_DecodeHeader(&hTp->parser.adts, &hTp->asc[0], hBs,
906*e5436536SAndroid Build Coastguard Worker ignoreBufferFullness);
907*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_OK) {
908*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
909*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
910*e5436536SAndroid Build Coastguard Worker }
911*e5436536SAndroid Build Coastguard Worker } else {
912*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbUpdateConfig(
913*e5436536SAndroid Build Coastguard Worker hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
914*e5436536SAndroid Build Coastguard Worker &configChanged);
915*e5436536SAndroid Build Coastguard Worker if (errC != 0) {
916*e5436536SAndroid Build Coastguard Worker if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
917*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_NEED_TO_RESTART;
918*e5436536SAndroid Build Coastguard Worker goto bail;
919*e5436536SAndroid Build Coastguard Worker } else {
920*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
921*e5436536SAndroid Build Coastguard Worker }
922*e5436536SAndroid Build Coastguard Worker } else {
923*e5436536SAndroid Build Coastguard Worker fConfigFound = 1;
924*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks =
925*e5436536SAndroid Build Coastguard Worker hTp->parser.adts.bs.num_raw_blocks + 1;
926*e5436536SAndroid Build Coastguard Worker }
927*e5436536SAndroid Build Coastguard Worker }
928*e5436536SAndroid Build Coastguard Worker
929*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
930*e5436536SAndroid Build Coastguard Worker if ((i == 0) && configChanged) {
931*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
932*e5436536SAndroid Build Coastguard Worker &hTp->asc[0]);
933*e5436536SAndroid Build Coastguard Worker if (errC != 0) {
934*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
935*e5436536SAndroid Build Coastguard Worker }
936*e5436536SAndroid Build Coastguard Worker }
937*e5436536SAndroid Build Coastguard Worker }
938*e5436536SAndroid Build Coastguard Worker /* if an error is detected terminate config parsing to avoid that an
939*e5436536SAndroid Build Coastguard Worker * invalid config is accepted in the second pass */
940*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_OK) {
941*e5436536SAndroid Build Coastguard Worker break;
942*e5436536SAndroid Build Coastguard Worker }
943*e5436536SAndroid Build Coastguard Worker }
944*e5436536SAndroid Build Coastguard Worker } else {
945*e5436536SAndroid Build Coastguard Worker /* Reset CRC because the next bits are the beginning of a
946*e5436536SAndroid Build Coastguard Worker * raw_data_block() */
947*e5436536SAndroid Build Coastguard Worker FDKcrcReset(&hTp->parser.adts.crcInfo);
948*e5436536SAndroid Build Coastguard Worker hTp->parser.adts.bs.num_pce_bits = 0;
949*e5436536SAndroid Build Coastguard Worker }
950*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
951*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks--;
952*e5436536SAndroid Build Coastguard Worker rawDataBlockLength = adtsRead_GetRawDataBlockLength(
953*e5436536SAndroid Build Coastguard Worker &hTp->parser.adts,
954*e5436536SAndroid Build Coastguard Worker (hTp->parser.adts.bs.num_raw_blocks - hTp->numberOfRawDataBlocks));
955*e5436536SAndroid Build Coastguard Worker if (rawDataBlockLength <= 0) {
956*e5436536SAndroid Build Coastguard Worker /* No further frame traversal possible. */
957*e5436536SAndroid Build Coastguard Worker fTraverseMoreFrames = 0;
958*e5436536SAndroid Build Coastguard Worker }
959*e5436536SAndroid Build Coastguard Worker syncLayerFrameBits = (hTp->parser.adts.bs.frame_length << 3) -
960*e5436536SAndroid Build Coastguard Worker (startPos - (INT)FDKgetValidBits(hBs)) -
961*e5436536SAndroid Build Coastguard Worker syncLength;
962*e5436536SAndroid Build Coastguard Worker if (syncLayerFrameBits <= 0) {
963*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
964*e5436536SAndroid Build Coastguard Worker }
965*e5436536SAndroid Build Coastguard Worker } else {
966*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = 0;
967*e5436536SAndroid Build Coastguard Worker }
968*e5436536SAndroid Build Coastguard Worker break;
969*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
970*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks <= 0) {
971*e5436536SAndroid Build Coastguard Worker syncLayerFrameBits = (INT)FDKreadBits(hBs, 13);
972*e5436536SAndroid Build Coastguard Worker hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
973*e5436536SAndroid Build Coastguard Worker syncLayerFrameBits <<= 3;
974*e5436536SAndroid Build Coastguard Worker }
975*e5436536SAndroid Build Coastguard Worker FDK_FALLTHROUGH;
976*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1:
977*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
978*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks <= 0) {
979*e5436536SAndroid Build Coastguard Worker hTp->globalFramePos = FDKgetValidBits(hBs);
980*e5436536SAndroid Build Coastguard Worker
981*e5436536SAndroid Build Coastguard Worker err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt,
982*e5436536SAndroid Build Coastguard Worker &hTp->callbacks, hTp->asc, &fConfigFound,
983*e5436536SAndroid Build Coastguard Worker ignoreBufferFullness);
984*e5436536SAndroid Build Coastguard Worker
985*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_OK) {
986*e5436536SAndroid Build Coastguard Worker if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) &&
987*e5436536SAndroid Build Coastguard Worker !TPDEC_IS_FATAL_ERROR(err)) {
988*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
989*e5436536SAndroid Build Coastguard Worker }
990*e5436536SAndroid Build Coastguard Worker } else {
991*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks =
992*e5436536SAndroid Build Coastguard Worker CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
993*e5436536SAndroid Build Coastguard Worker if (hTp->transportFmt == TT_MP4_LOAS) {
994*e5436536SAndroid Build Coastguard Worker syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
995*e5436536SAndroid Build Coastguard Worker if (syncLayerFrameBits <= 0) {
996*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
997*e5436536SAndroid Build Coastguard Worker }
998*e5436536SAndroid Build Coastguard Worker }
999*e5436536SAndroid Build Coastguard Worker }
1000*e5436536SAndroid Build Coastguard Worker } else {
1001*e5436536SAndroid Build Coastguard Worker err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
1002*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_OK) {
1003*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
1004*e5436536SAndroid Build Coastguard Worker }
1005*e5436536SAndroid Build Coastguard Worker }
1006*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
1007*e5436536SAndroid Build Coastguard Worker int layer;
1008*e5436536SAndroid Build Coastguard Worker rawDataBlockLength = 0;
1009*e5436536SAndroid Build Coastguard Worker for (layer = 0;
1010*e5436536SAndroid Build Coastguard Worker layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0);
1011*e5436536SAndroid Build Coastguard Worker layer += 1) {
1012*e5436536SAndroid Build Coastguard Worker rawDataBlockLength +=
1013*e5436536SAndroid Build Coastguard Worker CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer);
1014*e5436536SAndroid Build Coastguard Worker }
1015*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks--;
1016*e5436536SAndroid Build Coastguard Worker } else {
1017*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = 0;
1018*e5436536SAndroid Build Coastguard Worker }
1019*e5436536SAndroid Build Coastguard Worker break;
1020*e5436536SAndroid Build Coastguard Worker default: { syncLayerFrameBits = 0; } break;
1021*e5436536SAndroid Build Coastguard Worker }
1022*e5436536SAndroid Build Coastguard Worker
1023*e5436536SAndroid Build Coastguard Worker bail:
1024*e5436536SAndroid Build Coastguard Worker
1025*e5436536SAndroid Build Coastguard Worker *pRawDataBlockLength = rawDataBlockLength;
1026*e5436536SAndroid Build Coastguard Worker
1027*e5436536SAndroid Build Coastguard Worker if (pHeaderBits != NULL) {
1028*e5436536SAndroid Build Coastguard Worker *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
1029*e5436536SAndroid Build Coastguard Worker }
1030*e5436536SAndroid Build Coastguard Worker
1031*e5436536SAndroid Build Coastguard Worker for (int i = 0; i < (1 * 1); i++) {
1032*e5436536SAndroid Build Coastguard Worker /* If parsing error while config found, clear ctrlCFGChange-struct */
1033*e5436536SAndroid Build Coastguard Worker if (hTp->ctrlCFGChange[i].cfgChanged && err != TRANSPORTDEC_OK) {
1034*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = 0;
1035*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[i].flushCnt = 0;
1036*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[i].flushStatus = TPDEC_FLUSH_OFF;
1037*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[i].buildUpCnt = 0;
1038*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[i].buildUpStatus = TPDEC_BUILD_UP_OFF;
1039*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[i].cfgChanged = 0;
1040*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[i].contentChanged = 0;
1041*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[i].forceCfgChange = 0;
1042*e5436536SAndroid Build Coastguard Worker
1043*e5436536SAndroid Build Coastguard Worker hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
1044*e5436536SAndroid Build Coastguard Worker &hTp->ctrlCFGChange[i]);
1045*e5436536SAndroid Build Coastguard Worker }
1046*e5436536SAndroid Build Coastguard Worker }
1047*e5436536SAndroid Build Coastguard Worker
1048*e5436536SAndroid Build Coastguard Worker if (pfConfigFound != NULL) {
1049*e5436536SAndroid Build Coastguard Worker *pfConfigFound = fConfigFound;
1050*e5436536SAndroid Build Coastguard Worker }
1051*e5436536SAndroid Build Coastguard Worker
1052*e5436536SAndroid Build Coastguard Worker if (pfTraverseMoreFrames != NULL) {
1053*e5436536SAndroid Build Coastguard Worker *pfTraverseMoreFrames = fTraverseMoreFrames;
1054*e5436536SAndroid Build Coastguard Worker }
1055*e5436536SAndroid Build Coastguard Worker if (pSyncLayerFrameBits != NULL) {
1056*e5436536SAndroid Build Coastguard Worker *pSyncLayerFrameBits = syncLayerFrameBits;
1057*e5436536SAndroid Build Coastguard Worker }
1058*e5436536SAndroid Build Coastguard Worker
1059*e5436536SAndroid Build Coastguard Worker return err;
1060*e5436536SAndroid Build Coastguard Worker }
1061*e5436536SAndroid Build Coastguard Worker
1062*e5436536SAndroid Build Coastguard Worker /* How many bits to advance for synchronization search. */
1063*e5436536SAndroid Build Coastguard Worker #define TPDEC_SYNCSKIP 8
1064*e5436536SAndroid Build Coastguard Worker
synchronization(HANDLE_TRANSPORTDEC hTp,INT * pHeaderBits)1065*e5436536SAndroid Build Coastguard Worker static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
1066*e5436536SAndroid Build Coastguard Worker INT *pHeaderBits) {
1067*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
1068*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
1069*e5436536SAndroid Build Coastguard Worker
1070*e5436536SAndroid Build Coastguard Worker INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
1071*e5436536SAndroid Build Coastguard Worker INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
1072*e5436536SAndroid Build Coastguard Worker INT totalBits;
1073*e5436536SAndroid Build Coastguard Worker INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
1074*e5436536SAndroid Build Coastguard Worker INT numFramesTraversed = 0, fTraverseMoreFrames,
1075*e5436536SAndroid Build Coastguard Worker fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
1076*e5436536SAndroid Build Coastguard Worker INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious,
1077*e5436536SAndroid Build Coastguard Worker globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
1078*e5436536SAndroid Build Coastguard Worker INT ignoreBufferFullness =
1079*e5436536SAndroid Build Coastguard Worker hTp->flags &
1080*e5436536SAndroid Build Coastguard Worker (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK);
1081*e5436536SAndroid Build Coastguard Worker UINT endTpFrameBitsPrevious = 0;
1082*e5436536SAndroid Build Coastguard Worker
1083*e5436536SAndroid Build Coastguard Worker /* Synch parameters */
1084*e5436536SAndroid Build Coastguard Worker INT syncLength; /* Length of sync word in bits */
1085*e5436536SAndroid Build Coastguard Worker UINT syncWord; /* Sync word to be found */
1086*e5436536SAndroid Build Coastguard Worker UINT syncMask; /* Mask for sync word (for adding one bit, so comprising one
1087*e5436536SAndroid Build Coastguard Worker bit less) */
1088*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);
1089*e5436536SAndroid Build Coastguard Worker
1090*e5436536SAndroid Build Coastguard Worker totalBits = (INT)FDKgetValidBits(hBs);
1091*e5436536SAndroid Build Coastguard Worker
1092*e5436536SAndroid Build Coastguard Worker if (totalBits <= 0) {
1093*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1094*e5436536SAndroid Build Coastguard Worker goto bail;
1095*e5436536SAndroid Build Coastguard Worker }
1096*e5436536SAndroid Build Coastguard Worker
1097*e5436536SAndroid Build Coastguard Worker fTraverseMoreFrames =
1098*e5436536SAndroid Build Coastguard Worker (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) &&
1099*e5436536SAndroid Build Coastguard Worker !(hTp->flags & TPDEC_SYNCOK);
1100*e5436536SAndroid Build Coastguard Worker
1101*e5436536SAndroid Build Coastguard Worker /* Set transport specific sync parameters */
1102*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
1103*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
1104*e5436536SAndroid Build Coastguard Worker syncWord = ADTS_SYNCWORD;
1105*e5436536SAndroid Build Coastguard Worker syncLength = ADTS_SYNCLENGTH;
1106*e5436536SAndroid Build Coastguard Worker break;
1107*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
1108*e5436536SAndroid Build Coastguard Worker syncWord = 0x2B7;
1109*e5436536SAndroid Build Coastguard Worker syncLength = 11;
1110*e5436536SAndroid Build Coastguard Worker break;
1111*e5436536SAndroid Build Coastguard Worker default:
1112*e5436536SAndroid Build Coastguard Worker syncWord = 0;
1113*e5436536SAndroid Build Coastguard Worker syncLength = 0;
1114*e5436536SAndroid Build Coastguard Worker break;
1115*e5436536SAndroid Build Coastguard Worker }
1116*e5436536SAndroid Build Coastguard Worker
1117*e5436536SAndroid Build Coastguard Worker syncMask = (1 << syncLength) - 1;
1118*e5436536SAndroid Build Coastguard Worker
1119*e5436536SAndroid Build Coastguard Worker do {
1120*e5436536SAndroid Build Coastguard Worker INT bitsAvail = 0; /* Bits available in bitstream buffer */
1121*e5436536SAndroid Build Coastguard Worker INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries
1122*e5436536SAndroid Build Coastguard Worker */
1123*e5436536SAndroid Build Coastguard Worker UINT synch; /* Current sync word read from bitstream */
1124*e5436536SAndroid Build Coastguard Worker
1125*e5436536SAndroid Build Coastguard Worker headerBitsPrevious = headerBits;
1126*e5436536SAndroid Build Coastguard Worker
1127*e5436536SAndroid Build Coastguard Worker bitsAvail = (INT)FDKgetValidBits(hBs);
1128*e5436536SAndroid Build Coastguard Worker
1129*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks == 0) {
1130*e5436536SAndroid Build Coastguard Worker /* search synchword */
1131*e5436536SAndroid Build Coastguard Worker
1132*e5436536SAndroid Build Coastguard Worker FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0);
1133*e5436536SAndroid Build Coastguard Worker
1134*e5436536SAndroid Build Coastguard Worker if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) {
1135*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1136*e5436536SAndroid Build Coastguard Worker headerBits = 0;
1137*e5436536SAndroid Build Coastguard Worker } else {
1138*e5436536SAndroid Build Coastguard Worker synch = FDKreadBits(hBs, syncLength);
1139*e5436536SAndroid Build Coastguard Worker
1140*e5436536SAndroid Build Coastguard Worker if (!(hTp->flags & TPDEC_SYNCOK)) {
1141*e5436536SAndroid Build Coastguard Worker for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP;
1142*e5436536SAndroid Build Coastguard Worker bitsAvail -= TPDEC_SYNCSKIP) {
1143*e5436536SAndroid Build Coastguard Worker if (synch == syncWord) {
1144*e5436536SAndroid Build Coastguard Worker break;
1145*e5436536SAndroid Build Coastguard Worker }
1146*e5436536SAndroid Build Coastguard Worker synch = ((synch << TPDEC_SYNCSKIP) & syncMask) |
1147*e5436536SAndroid Build Coastguard Worker FDKreadBits(hBs, TPDEC_SYNCSKIP);
1148*e5436536SAndroid Build Coastguard Worker }
1149*e5436536SAndroid Build Coastguard Worker }
1150*e5436536SAndroid Build Coastguard Worker if (synch != syncWord) {
1151*e5436536SAndroid Build Coastguard Worker /* No correct syncword found. */
1152*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
1153*e5436536SAndroid Build Coastguard Worker } else {
1154*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_OK;
1155*e5436536SAndroid Build Coastguard Worker }
1156*e5436536SAndroid Build Coastguard Worker headerBits = syncLength;
1157*e5436536SAndroid Build Coastguard Worker }
1158*e5436536SAndroid Build Coastguard Worker } else {
1159*e5436536SAndroid Build Coastguard Worker headerBits = 0;
1160*e5436536SAndroid Build Coastguard Worker }
1161*e5436536SAndroid Build Coastguard Worker
1162*e5436536SAndroid Build Coastguard Worker /* Save previous raw data block data */
1163*e5436536SAndroid Build Coastguard Worker rawDataBlockLengthPrevious = rawDataBlockLength;
1164*e5436536SAndroid Build Coastguard Worker numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;
1165*e5436536SAndroid Build Coastguard Worker
1166*e5436536SAndroid Build Coastguard Worker /* Parse transport header (raw data block granularity) */
1167*e5436536SAndroid Build Coastguard Worker
1168*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
1169*e5436536SAndroid Build Coastguard Worker err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness,
1170*e5436536SAndroid Build Coastguard Worker &rawDataBlockLength, &fTraverseMoreFrames,
1171*e5436536SAndroid Build Coastguard Worker &syncLayerFrameBits, &fConfigFound,
1172*e5436536SAndroid Build Coastguard Worker &headerBits);
1173*e5436536SAndroid Build Coastguard Worker if (headerBits > bitsAvail) {
1174*e5436536SAndroid Build Coastguard Worker err = (headerBits < (INT)hBs->hBitBuf.bufBits)
1175*e5436536SAndroid Build Coastguard Worker ? TRANSPORTDEC_NOT_ENOUGH_BITS
1176*e5436536SAndroid Build Coastguard Worker : TRANSPORTDEC_SYNC_ERROR;
1177*e5436536SAndroid Build Coastguard Worker }
1178*e5436536SAndroid Build Coastguard Worker if (TPDEC_IS_FATAL_ERROR(err)) {
1179*e5436536SAndroid Build Coastguard Worker /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
1180*e5436536SAndroid Build Coastguard Worker * next time. Ensure that the bit amount lands at a multiple of
1181*e5436536SAndroid Build Coastguard Worker * TPDEC_SYNCSKIP. */
1182*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(
1183*e5436536SAndroid Build Coastguard Worker hBs, -headerBits + TPDEC_SYNCSKIP + (bitsAvail % TPDEC_SYNCSKIP));
1184*e5436536SAndroid Build Coastguard Worker
1185*e5436536SAndroid Build Coastguard Worker goto bail;
1186*e5436536SAndroid Build Coastguard Worker }
1187*e5436536SAndroid Build Coastguard Worker }
1188*e5436536SAndroid Build Coastguard Worker
1189*e5436536SAndroid Build Coastguard Worker bitsAvail -= headerBits;
1190*e5436536SAndroid Build Coastguard Worker
1191*e5436536SAndroid Build Coastguard Worker checkLengthBits = syncLayerFrameBits;
1192*e5436536SAndroid Build Coastguard Worker
1193*e5436536SAndroid Build Coastguard Worker /* Check if the whole frame would fit the bitstream buffer */
1194*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
1195*e5436536SAndroid Build Coastguard Worker if ((checkLengthBits + headerBits) > (((8192 * 4) << 3) - 7)) {
1196*e5436536SAndroid Build Coastguard Worker /* We assume that the size of the transport bit buffer has been
1197*e5436536SAndroid Build Coastguard Worker chosen to meet all system requirements, thus this condition
1198*e5436536SAndroid Build Coastguard Worker is considered a synchronisation error. */
1199*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
1200*e5436536SAndroid Build Coastguard Worker } else {
1201*e5436536SAndroid Build Coastguard Worker if (bitsAvail < checkLengthBits) {
1202*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1203*e5436536SAndroid Build Coastguard Worker }
1204*e5436536SAndroid Build Coastguard Worker }
1205*e5436536SAndroid Build Coastguard Worker }
1206*e5436536SAndroid Build Coastguard Worker
1207*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1208*e5436536SAndroid Build Coastguard Worker break;
1209*e5436536SAndroid Build Coastguard Worker }
1210*e5436536SAndroid Build Coastguard Worker
1211*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_SYNC_ERROR) {
1212*e5436536SAndroid Build Coastguard Worker int bits;
1213*e5436536SAndroid Build Coastguard Worker
1214*e5436536SAndroid Build Coastguard Worker /* Enforce re-sync of transport headers. */
1215*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = 0;
1216*e5436536SAndroid Build Coastguard Worker
1217*e5436536SAndroid Build Coastguard Worker /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
1218*e5436536SAndroid Build Coastguard Worker bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
1219*e5436536SAndroid Build Coastguard Worker /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
1220*e5436536SAndroid Build Coastguard Worker * next time. */
1221*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
1222*e5436536SAndroid Build Coastguard Worker headerBits = 0;
1223*e5436536SAndroid Build Coastguard Worker }
1224*e5436536SAndroid Build Coastguard Worker
1225*e5436536SAndroid Build Coastguard Worker /* Frame traversal */
1226*e5436536SAndroid Build Coastguard Worker if (fTraverseMoreFrames) {
1227*e5436536SAndroid Build Coastguard Worker /* Save parser context for early config discovery "rewind all frames" */
1228*e5436536SAndroid Build Coastguard Worker if ((hTp->flags & TPDEC_EARLY_CONFIG) &&
1229*e5436536SAndroid Build Coastguard Worker !(hTp->flags & TPDEC_MINIMIZE_DELAY)) {
1230*e5436536SAndroid Build Coastguard Worker /* ignore buffer fullness if just traversing additional frames for ECD
1231*e5436536SAndroid Build Coastguard Worker */
1232*e5436536SAndroid Build Coastguard Worker ignoreBufferFullness = 1;
1233*e5436536SAndroid Build Coastguard Worker
1234*e5436536SAndroid Build Coastguard Worker /* Save context in order to return later */
1235*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK && startPosFirstFrame == -1) {
1236*e5436536SAndroid Build Coastguard Worker startPosFirstFrame = FDKgetValidBits(hBs);
1237*e5436536SAndroid Build Coastguard Worker numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
1238*e5436536SAndroid Build Coastguard Worker globalFramePosFirstFrame = hTp->globalFramePos;
1239*e5436536SAndroid Build Coastguard Worker rawDataBlockLengthFirstFrame = rawDataBlockLength;
1240*e5436536SAndroid Build Coastguard Worker headerBitsFirstFrame = headerBits;
1241*e5436536SAndroid Build Coastguard Worker errFirstFrame = err;
1242*e5436536SAndroid Build Coastguard Worker FDKmemcpy(contextFirstFrame, &hTp->parser,
1243*e5436536SAndroid Build Coastguard Worker sizeof(transportdec_parser_t));
1244*e5436536SAndroid Build Coastguard Worker }
1245*e5436536SAndroid Build Coastguard Worker
1246*e5436536SAndroid Build Coastguard Worker /* Break when config was found or it is not possible anymore to find a
1247*e5436536SAndroid Build Coastguard Worker * config */
1248*e5436536SAndroid Build Coastguard Worker if (startPosFirstFrame != -1 &&
1249*e5436536SAndroid Build Coastguard Worker (fConfigFound || err != TRANSPORTDEC_OK)) {
1250*e5436536SAndroid Build Coastguard Worker /* In case of ECD and sync error, do not rewind anywhere. */
1251*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_SYNC_ERROR) {
1252*e5436536SAndroid Build Coastguard Worker startPosFirstFrame = -1;
1253*e5436536SAndroid Build Coastguard Worker fConfigFound = 0;
1254*e5436536SAndroid Build Coastguard Worker numFramesTraversed = 0;
1255*e5436536SAndroid Build Coastguard Worker }
1256*e5436536SAndroid Build Coastguard Worker break;
1257*e5436536SAndroid Build Coastguard Worker }
1258*e5436536SAndroid Build Coastguard Worker }
1259*e5436536SAndroid Build Coastguard Worker
1260*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
1261*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, rawDataBlockLength);
1262*e5436536SAndroid Build Coastguard Worker numFramesTraversed++;
1263*e5436536SAndroid Build Coastguard Worker endTpFrameBitsPrevious = (INT)FDKgetValidBits(hBs);
1264*e5436536SAndroid Build Coastguard Worker /* Ignore error here itentionally. */
1265*e5436536SAndroid Build Coastguard Worker transportDec_AdjustEndOfAccessUnit(hTp);
1266*e5436536SAndroid Build Coastguard Worker endTpFrameBitsPrevious -= FDKgetValidBits(hBs);
1267*e5436536SAndroid Build Coastguard Worker }
1268*e5436536SAndroid Build Coastguard Worker }
1269*e5436536SAndroid Build Coastguard Worker } while (fTraverseMoreFrames ||
1270*e5436536SAndroid Build Coastguard Worker (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
1271*e5436536SAndroid Build Coastguard Worker
1272*e5436536SAndroid Build Coastguard Worker /* Restore context in case of ECD frame traversal */
1273*e5436536SAndroid Build Coastguard Worker if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
1274*e5436536SAndroid Build Coastguard Worker FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
1275*e5436536SAndroid Build Coastguard Worker FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
1276*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
1277*e5436536SAndroid Build Coastguard Worker hTp->globalFramePos = globalFramePosFirstFrame;
1278*e5436536SAndroid Build Coastguard Worker rawDataBlockLength = rawDataBlockLengthFirstFrame;
1279*e5436536SAndroid Build Coastguard Worker headerBits = headerBitsFirstFrame;
1280*e5436536SAndroid Build Coastguard Worker err = errFirstFrame;
1281*e5436536SAndroid Build Coastguard Worker numFramesTraversed = 0;
1282*e5436536SAndroid Build Coastguard Worker }
1283*e5436536SAndroid Build Coastguard Worker
1284*e5436536SAndroid Build Coastguard Worker /* Additional burst data mode buffer fullness check. */
1285*e5436536SAndroid Build Coastguard Worker if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
1286*e5436536SAndroid Build Coastguard Worker TPDEC_SYNCOK)) &&
1287*e5436536SAndroid Build Coastguard Worker err == TRANSPORTDEC_OK) {
1288*e5436536SAndroid Build Coastguard Worker err =
1289*e5436536SAndroid Build Coastguard Worker additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
1290*e5436536SAndroid Build Coastguard Worker (INT)FDKgetValidBits(hBs) - syncLayerFrameBits);
1291*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1292*e5436536SAndroid Build Coastguard Worker hTp->holdOffFrames++;
1293*e5436536SAndroid Build Coastguard Worker }
1294*e5436536SAndroid Build Coastguard Worker }
1295*e5436536SAndroid Build Coastguard Worker
1296*e5436536SAndroid Build Coastguard Worker /* Rewind for retry because of not enough bits */
1297*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1298*e5436536SAndroid Build Coastguard Worker FDKpushBack(hBs, headerBits);
1299*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
1300*e5436536SAndroid Build Coastguard Worker headerBits = 0;
1301*e5436536SAndroid Build Coastguard Worker rawDataBlockLength = rawDataBlockLengthPrevious;
1302*e5436536SAndroid Build Coastguard Worker } else {
1303*e5436536SAndroid Build Coastguard Worker /* reset hold off frame counter */
1304*e5436536SAndroid Build Coastguard Worker hTp->holdOffFrames = 0;
1305*e5436536SAndroid Build Coastguard Worker }
1306*e5436536SAndroid Build Coastguard Worker
1307*e5436536SAndroid Build Coastguard Worker /* Return to last good frame in case of frame traversal but not ECD. */
1308*e5436536SAndroid Build Coastguard Worker if (numFramesTraversed > 0) {
1309*e5436536SAndroid Build Coastguard Worker FDKpushBack(hBs, rawDataBlockLengthPrevious + endTpFrameBitsPrevious);
1310*e5436536SAndroid Build Coastguard Worker if (err != TRANSPORTDEC_OK) {
1311*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
1312*e5436536SAndroid Build Coastguard Worker headerBits = headerBitsPrevious;
1313*e5436536SAndroid Build Coastguard Worker rawDataBlockLength = rawDataBlockLengthPrevious;
1314*e5436536SAndroid Build Coastguard Worker }
1315*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_OK;
1316*e5436536SAndroid Build Coastguard Worker }
1317*e5436536SAndroid Build Coastguard Worker
1318*e5436536SAndroid Build Coastguard Worker bail:
1319*e5436536SAndroid Build Coastguard Worker hTp->auLength[0] = rawDataBlockLength;
1320*e5436536SAndroid Build Coastguard Worker
1321*e5436536SAndroid Build Coastguard Worker /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, where the bit
1322*e5436536SAndroid Build Coastguard Worker buffer is already full, or no new burst packet fits. Recover by advancing
1323*e5436536SAndroid Build Coastguard Worker the bit buffer. */
1324*e5436536SAndroid Build Coastguard Worker if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&
1325*e5436536SAndroid Build Coastguard Worker (FDKgetValidBits(hBs) >=
1326*e5436536SAndroid Build Coastguard Worker (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) -
1327*e5436536SAndroid Build Coastguard Worker 7))) {
1328*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, TPDEC_SYNCSKIP);
1329*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_SYNC_ERROR;
1330*e5436536SAndroid Build Coastguard Worker }
1331*e5436536SAndroid Build Coastguard Worker
1332*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
1333*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_SYNCOK;
1334*e5436536SAndroid Build Coastguard Worker }
1335*e5436536SAndroid Build Coastguard Worker
1336*e5436536SAndroid Build Coastguard Worker if (fConfigFound) {
1337*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_CONFIG_FOUND;
1338*e5436536SAndroid Build Coastguard Worker }
1339*e5436536SAndroid Build Coastguard Worker
1340*e5436536SAndroid Build Coastguard Worker if (pHeaderBits != NULL) {
1341*e5436536SAndroid Build Coastguard Worker *pHeaderBits = headerBits;
1342*e5436536SAndroid Build Coastguard Worker }
1343*e5436536SAndroid Build Coastguard Worker
1344*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_SYNC_ERROR) {
1345*e5436536SAndroid Build Coastguard Worker hTp->flags &= ~TPDEC_SYNCOK;
1346*e5436536SAndroid Build Coastguard Worker }
1347*e5436536SAndroid Build Coastguard Worker
1348*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);
1349*e5436536SAndroid Build Coastguard Worker
1350*e5436536SAndroid Build Coastguard Worker return err;
1351*e5436536SAndroid Build Coastguard Worker }
1352*e5436536SAndroid Build Coastguard Worker
1353*e5436536SAndroid Build Coastguard Worker /**
1354*e5436536SAndroid Build Coastguard Worker * \brief Synchronize to stream and estimate the amount of missing access units
1355*e5436536SAndroid Build Coastguard Worker * due to a current synchronization error in case of constant average bit rate.
1356*e5436536SAndroid Build Coastguard Worker */
transportDec_readStream(HANDLE_TRANSPORTDEC hTp,const UINT layer)1357*e5436536SAndroid Build Coastguard Worker static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp,
1358*e5436536SAndroid Build Coastguard Worker const UINT layer) {
1359*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
1360*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
1361*e5436536SAndroid Build Coastguard Worker
1362*e5436536SAndroid Build Coastguard Worker INT headerBits;
1363*e5436536SAndroid Build Coastguard Worker INT bitDistance, bfDelta;
1364*e5436536SAndroid Build Coastguard Worker
1365*e5436536SAndroid Build Coastguard Worker /* Obtain distance to next synch word */
1366*e5436536SAndroid Build Coastguard Worker bitDistance = (INT)FDKgetValidBits(hBs);
1367*e5436536SAndroid Build Coastguard Worker error = synchronization(hTp, &headerBits);
1368*e5436536SAndroid Build Coastguard Worker bitDistance -= (INT)FDKgetValidBits(hBs);
1369*e5436536SAndroid Build Coastguard Worker
1370*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(bitDistance >= 0);
1371*e5436536SAndroid Build Coastguard Worker
1372*e5436536SAndroid Build Coastguard Worker INT nAU = -1;
1373*e5436536SAndroid Build Coastguard Worker
1374*e5436536SAndroid Build Coastguard Worker if (error == TRANSPORTDEC_SYNC_ERROR ||
1375*e5436536SAndroid Build Coastguard Worker (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
1376*e5436536SAndroid Build Coastguard Worker /* Check if estimating lost access units is feasible. */
1377*e5436536SAndroid Build Coastguard Worker if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 &&
1378*e5436536SAndroid Build Coastguard Worker hTp->asc[0].m_samplingFrequency > 0) {
1379*e5436536SAndroid Build Coastguard Worker if (error == TRANSPORTDEC_OK) {
1380*e5436536SAndroid Build Coastguard Worker int aj;
1381*e5436536SAndroid Build Coastguard Worker
1382*e5436536SAndroid Build Coastguard Worker aj = transportDec_GetBufferFullness(hTp);
1383*e5436536SAndroid Build Coastguard Worker if (aj > 0) {
1384*e5436536SAndroid Build Coastguard Worker bfDelta = aj;
1385*e5436536SAndroid Build Coastguard Worker } else {
1386*e5436536SAndroid Build Coastguard Worker bfDelta = 0;
1387*e5436536SAndroid Build Coastguard Worker }
1388*e5436536SAndroid Build Coastguard Worker /* sync was ok: last of a series of bad access units. */
1389*e5436536SAndroid Build Coastguard Worker hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
1390*e5436536SAndroid Build Coastguard Worker /* Add up bitDistance until end of the current frame. Later we substract
1391*e5436536SAndroid Build Coastguard Worker this frame from the grand total, since this current successfully
1392*e5436536SAndroid Build Coastguard Worker synchronized frame should not be skipped of course; but it must be
1393*e5436536SAndroid Build Coastguard Worker accounted into the bufferfulness math. */
1394*e5436536SAndroid Build Coastguard Worker bitDistance += hTp->auLength[0];
1395*e5436536SAndroid Build Coastguard Worker } else {
1396*e5436536SAndroid Build Coastguard Worker if (!(hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
1397*e5436536SAndroid Build Coastguard Worker /* sync not ok: one of many bad access units. */
1398*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
1399*e5436536SAndroid Build Coastguard Worker bfDelta = -(INT)hTp->lastValidBufferFullness;
1400*e5436536SAndroid Build Coastguard Worker } else {
1401*e5436536SAndroid Build Coastguard Worker bfDelta = 0;
1402*e5436536SAndroid Build Coastguard Worker }
1403*e5436536SAndroid Build Coastguard Worker }
1404*e5436536SAndroid Build Coastguard Worker
1405*e5436536SAndroid Build Coastguard Worker {
1406*e5436536SAndroid Build Coastguard Worker int num, denom;
1407*e5436536SAndroid Build Coastguard Worker
1408*e5436536SAndroid Build Coastguard Worker /* Obtain estimate of number of lost frames */
1409*e5436536SAndroid Build Coastguard Worker num = (INT)hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) +
1410*e5436536SAndroid Build Coastguard Worker hTp->remainder;
1411*e5436536SAndroid Build Coastguard Worker denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
1412*e5436536SAndroid Build Coastguard Worker if (num > 0) {
1413*e5436536SAndroid Build Coastguard Worker nAU = num / denom;
1414*e5436536SAndroid Build Coastguard Worker hTp->remainder = num % denom;
1415*e5436536SAndroid Build Coastguard Worker } else {
1416*e5436536SAndroid Build Coastguard Worker hTp->remainder = num;
1417*e5436536SAndroid Build Coastguard Worker }
1418*e5436536SAndroid Build Coastguard Worker
1419*e5436536SAndroid Build Coastguard Worker if (error == TRANSPORTDEC_OK) {
1420*e5436536SAndroid Build Coastguard Worker /* Final adjustment of remainder, taken -1 into account because
1421*e5436536SAndroid Build Coastguard Worker current frame should not be skipped, thus substract -1 or do
1422*e5436536SAndroid Build Coastguard Worker nothing instead of +1-1 accordingly. */
1423*e5436536SAndroid Build Coastguard Worker if ((denom - hTp->remainder) >= hTp->remainder) {
1424*e5436536SAndroid Build Coastguard Worker nAU--;
1425*e5436536SAndroid Build Coastguard Worker }
1426*e5436536SAndroid Build Coastguard Worker
1427*e5436536SAndroid Build Coastguard Worker if (nAU < 0) {
1428*e5436536SAndroid Build Coastguard Worker /* There was one frame too much concealed, so unfortunately we will
1429*e5436536SAndroid Build Coastguard Worker * have to skip one good frame. */
1430*e5436536SAndroid Build Coastguard Worker transportDec_EndAccessUnit(hTp);
1431*e5436536SAndroid Build Coastguard Worker error = synchronization(hTp, &headerBits);
1432*e5436536SAndroid Build Coastguard Worker nAU = -1;
1433*e5436536SAndroid Build Coastguard Worker }
1434*e5436536SAndroid Build Coastguard Worker hTp->remainder = 0;
1435*e5436536SAndroid Build Coastguard Worker /* Enforce last missed frames to be concealed. */
1436*e5436536SAndroid Build Coastguard Worker if (nAU > 0) {
1437*e5436536SAndroid Build Coastguard Worker FDKpushBack(hBs, headerBits);
1438*e5436536SAndroid Build Coastguard Worker }
1439*e5436536SAndroid Build Coastguard Worker }
1440*e5436536SAndroid Build Coastguard Worker }
1441*e5436536SAndroid Build Coastguard Worker }
1442*e5436536SAndroid Build Coastguard Worker }
1443*e5436536SAndroid Build Coastguard Worker
1444*e5436536SAndroid Build Coastguard Worker /* Be sure that lost frames are handled correctly. This is necessary due to
1445*e5436536SAndroid Build Coastguard Worker some sync error sequences where later it turns out that there is not enough
1446*e5436536SAndroid Build Coastguard Worker data, but the bits upto the sync word are discarded, thus causing a value
1447*e5436536SAndroid Build Coastguard Worker of nAU > 0 */
1448*e5436536SAndroid Build Coastguard Worker if (nAU > 0) {
1449*e5436536SAndroid Build Coastguard Worker error = TRANSPORTDEC_SYNC_ERROR;
1450*e5436536SAndroid Build Coastguard Worker }
1451*e5436536SAndroid Build Coastguard Worker
1452*e5436536SAndroid Build Coastguard Worker hTp->missingAccessUnits = nAU;
1453*e5436536SAndroid Build Coastguard Worker
1454*e5436536SAndroid Build Coastguard Worker return error;
1455*e5436536SAndroid Build Coastguard Worker }
1456*e5436536SAndroid Build Coastguard Worker
1457*e5436536SAndroid Build Coastguard Worker /* returns error code */
transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1458*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
1459*e5436536SAndroid Build Coastguard Worker const UINT layer) {
1460*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1461*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs;
1462*e5436536SAndroid Build Coastguard Worker
1463*e5436536SAndroid Build Coastguard Worker if (!hTp) {
1464*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_INVALID_PARAMETER;
1465*e5436536SAndroid Build Coastguard Worker }
1466*e5436536SAndroid Build Coastguard Worker
1467*e5436536SAndroid Build Coastguard Worker hBs = &hTp->bitStream[layer];
1468*e5436536SAndroid Build Coastguard Worker
1469*e5436536SAndroid Build Coastguard Worker if ((INT)FDKgetValidBits(hBs) <= 0) {
1470*e5436536SAndroid Build Coastguard Worker /* This is only relevant for RAW and ADIF cases.
1471*e5436536SAndroid Build Coastguard Worker * For streaming formats err will get overwritten. */
1472*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1473*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = 0;
1474*e5436536SAndroid Build Coastguard Worker }
1475*e5436536SAndroid Build Coastguard Worker
1476*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
1477*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADIF:
1478*e5436536SAndroid Build Coastguard Worker /* Read header if not already done */
1479*e5436536SAndroid Build Coastguard Worker if (!(hTp->flags & TPDEC_CONFIG_FOUND)) {
1480*e5436536SAndroid Build Coastguard Worker int i;
1481*e5436536SAndroid Build Coastguard Worker CProgramConfig *pce;
1482*e5436536SAndroid Build Coastguard Worker INT bsStart = FDKgetValidBits(hBs);
1483*e5436536SAndroid Build Coastguard Worker UCHAR configChanged = 0;
1484*e5436536SAndroid Build Coastguard Worker UCHAR configMode = AC_CM_DET_CFG_CHANGE;
1485*e5436536SAndroid Build Coastguard Worker
1486*e5436536SAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
1487*e5436536SAndroid Build Coastguard Worker if (i > 0) {
1488*e5436536SAndroid Build Coastguard Worker FDKpushBack(hBs, bsStart - (INT)FDKgetValidBits(hBs));
1489*e5436536SAndroid Build Coastguard Worker configMode = AC_CM_ALLOC_MEM;
1490*e5436536SAndroid Build Coastguard Worker }
1491*e5436536SAndroid Build Coastguard Worker
1492*e5436536SAndroid Build Coastguard Worker AudioSpecificConfig_Init(&hTp->asc[0]);
1493*e5436536SAndroid Build Coastguard Worker pce = &hTp->asc[0].m_progrConfigElement;
1494*e5436536SAndroid Build Coastguard Worker err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
1495*e5436536SAndroid Build Coastguard Worker if (err) goto bail;
1496*e5436536SAndroid Build Coastguard Worker
1497*e5436536SAndroid Build Coastguard Worker /* Map adif header to ASC */
1498*e5436536SAndroid Build Coastguard Worker hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
1499*e5436536SAndroid Build Coastguard Worker hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
1500*e5436536SAndroid Build Coastguard Worker hTp->asc[0].m_samplingFrequency =
1501*e5436536SAndroid Build Coastguard Worker SamplingRateTable[pce->SamplingFrequencyIndex];
1502*e5436536SAndroid Build Coastguard Worker hTp->asc[0].m_channelConfiguration = 0;
1503*e5436536SAndroid Build Coastguard Worker hTp->asc[0].m_samplesPerFrame = 1024;
1504*e5436536SAndroid Build Coastguard Worker hTp->avgBitRate = hTp->parser.adif.BitRate;
1505*e5436536SAndroid Build Coastguard Worker
1506*e5436536SAndroid Build Coastguard Worker /* Call callback to decoder. */
1507*e5436536SAndroid Build Coastguard Worker {
1508*e5436536SAndroid Build Coastguard Worker int errC;
1509*e5436536SAndroid Build Coastguard Worker
1510*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbUpdateConfig(
1511*e5436536SAndroid Build Coastguard Worker hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
1512*e5436536SAndroid Build Coastguard Worker &configChanged);
1513*e5436536SAndroid Build Coastguard Worker if (errC == 0) {
1514*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_CONFIG_FOUND;
1515*e5436536SAndroid Build Coastguard Worker } else {
1516*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
1517*e5436536SAndroid Build Coastguard Worker goto bail;
1518*e5436536SAndroid Build Coastguard Worker }
1519*e5436536SAndroid Build Coastguard Worker }
1520*e5436536SAndroid Build Coastguard Worker
1521*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
1522*e5436536SAndroid Build Coastguard Worker if ((i == 0) && configChanged) {
1523*e5436536SAndroid Build Coastguard Worker int errC;
1524*e5436536SAndroid Build Coastguard Worker errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
1525*e5436536SAndroid Build Coastguard Worker &hTp->asc[0]);
1526*e5436536SAndroid Build Coastguard Worker if (errC != 0) {
1527*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_PARSE_ERROR;
1528*e5436536SAndroid Build Coastguard Worker }
1529*e5436536SAndroid Build Coastguard Worker }
1530*e5436536SAndroid Build Coastguard Worker }
1531*e5436536SAndroid Build Coastguard Worker }
1532*e5436536SAndroid Build Coastguard Worker }
1533*e5436536SAndroid Build Coastguard Worker hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */
1534*e5436536SAndroid Build Coastguard Worker break;
1535*e5436536SAndroid Build Coastguard Worker
1536*e5436536SAndroid Build Coastguard Worker case TT_MP4_RAW:
1537*e5436536SAndroid Build Coastguard Worker case TT_DRM:
1538*e5436536SAndroid Build Coastguard Worker /* One Access Unit was filled into buffer.
1539*e5436536SAndroid Build Coastguard Worker So get the length out of the buffer. */
1540*e5436536SAndroid Build Coastguard Worker hTp->auLength[layer] = FDKgetValidBits(hBs);
1541*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_SYNCOK;
1542*e5436536SAndroid Build Coastguard Worker break;
1543*e5436536SAndroid Build Coastguard Worker
1544*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
1545*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1:
1546*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
1547*e5436536SAndroid Build Coastguard Worker int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND;
1548*e5436536SAndroid Build Coastguard Worker err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer],
1549*e5436536SAndroid Build Coastguard Worker NULL, NULL, &fConfigFound, NULL);
1550*e5436536SAndroid Build Coastguard Worker if (fConfigFound) {
1551*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_CONFIG_FOUND;
1552*e5436536SAndroid Build Coastguard Worker }
1553*e5436536SAndroid Build Coastguard Worker }
1554*e5436536SAndroid Build Coastguard Worker break;
1555*e5436536SAndroid Build Coastguard Worker
1556*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
1557*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
1558*e5436536SAndroid Build Coastguard Worker err = transportDec_readStream(hTp, layer);
1559*e5436536SAndroid Build Coastguard Worker break;
1560*e5436536SAndroid Build Coastguard Worker
1561*e5436536SAndroid Build Coastguard Worker default:
1562*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
1563*e5436536SAndroid Build Coastguard Worker break;
1564*e5436536SAndroid Build Coastguard Worker }
1565*e5436536SAndroid Build Coastguard Worker
1566*e5436536SAndroid Build Coastguard Worker if (err == TRANSPORTDEC_OK) {
1567*e5436536SAndroid Build Coastguard Worker hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
1568*e5436536SAndroid Build Coastguard Worker } else {
1569*e5436536SAndroid Build Coastguard Worker hTp->accessUnitAnchor[layer] = 0;
1570*e5436536SAndroid Build Coastguard Worker }
1571*e5436536SAndroid Build Coastguard Worker
1572*e5436536SAndroid Build Coastguard Worker bail:
1573*e5436536SAndroid Build Coastguard Worker return err;
1574*e5436536SAndroid Build Coastguard Worker }
1575*e5436536SAndroid Build Coastguard Worker
transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,const UINT layer,CSAudioSpecificConfig * asc)1576*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
1577*e5436536SAndroid Build Coastguard Worker const UINT layer,
1578*e5436536SAndroid Build Coastguard Worker CSAudioSpecificConfig *asc) {
1579*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1580*e5436536SAndroid Build Coastguard Worker
1581*e5436536SAndroid Build Coastguard Worker if (hTp != NULL) {
1582*e5436536SAndroid Build Coastguard Worker *asc = hTp->asc[layer];
1583*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_OK;
1584*e5436536SAndroid Build Coastguard Worker } else {
1585*e5436536SAndroid Build Coastguard Worker err = TRANSPORTDEC_INVALID_PARAMETER;
1586*e5436536SAndroid Build Coastguard Worker }
1587*e5436536SAndroid Build Coastguard Worker return err;
1588*e5436536SAndroid Build Coastguard Worker }
1589*e5436536SAndroid Build Coastguard Worker
transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1590*e5436536SAndroid Build Coastguard Worker INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
1591*e5436536SAndroid Build Coastguard Worker const UINT layer) {
1592*e5436536SAndroid Build Coastguard Worker INT bits;
1593*e5436536SAndroid Build Coastguard Worker
1594*e5436536SAndroid Build Coastguard Worker if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
1595*e5436536SAndroid Build Coastguard Worker bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]);
1596*e5436536SAndroid Build Coastguard Worker if (bits >= 0) {
1597*e5436536SAndroid Build Coastguard Worker bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits);
1598*e5436536SAndroid Build Coastguard Worker }
1599*e5436536SAndroid Build Coastguard Worker } else {
1600*e5436536SAndroid Build Coastguard Worker bits = FDKgetValidBits(&hTp->bitStream[layer]);
1601*e5436536SAndroid Build Coastguard Worker }
1602*e5436536SAndroid Build Coastguard Worker
1603*e5436536SAndroid Build Coastguard Worker return bits;
1604*e5436536SAndroid Build Coastguard Worker }
1605*e5436536SAndroid Build Coastguard Worker
transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,const UINT layer)1606*e5436536SAndroid Build Coastguard Worker INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
1607*e5436536SAndroid Build Coastguard Worker const UINT layer) {
1608*e5436536SAndroid Build Coastguard Worker return hTp->auLength[layer];
1609*e5436536SAndroid Build Coastguard Worker }
1610*e5436536SAndroid Build Coastguard Worker
transportDec_GetMissingAccessUnitCount(INT * pNAccessUnits,HANDLE_TRANSPORTDEC hTp)1611*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
1612*e5436536SAndroid Build Coastguard Worker INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) {
1613*e5436536SAndroid Build Coastguard Worker *pNAccessUnits = hTp->missingAccessUnits;
1614*e5436536SAndroid Build Coastguard Worker
1615*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_OK;
1616*e5436536SAndroid Build Coastguard Worker }
1617*e5436536SAndroid Build Coastguard Worker
1618*e5436536SAndroid Build Coastguard Worker /* Inform the transportDec layer that reading of access unit has finished. */
transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp)1619*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) {
1620*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1621*e5436536SAndroid Build Coastguard Worker
1622*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
1623*e5436536SAndroid Build Coastguard Worker case TT_MP4_LOAS:
1624*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP0:
1625*e5436536SAndroid Build Coastguard Worker case TT_MP4_LATM_MCP1: {
1626*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
1627*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks == 0) {
1628*e5436536SAndroid Build Coastguard Worker /* Read other data if available. */
1629*e5436536SAndroid Build Coastguard Worker if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) {
1630*e5436536SAndroid Build Coastguard Worker int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm);
1631*e5436536SAndroid Build Coastguard Worker
1632*e5436536SAndroid Build Coastguard Worker if ((INT)FDKgetValidBits(hBs) >= otherDataLen) {
1633*e5436536SAndroid Build Coastguard Worker FDKpushFor(hBs, otherDataLen);
1634*e5436536SAndroid Build Coastguard Worker } else {
1635*e5436536SAndroid Build Coastguard Worker /* Do byte align at the end of AudioMuxElement. */
1636*e5436536SAndroid Build Coastguard Worker if (hTp->numberOfRawDataBlocks == 0) {
1637*e5436536SAndroid Build Coastguard Worker FDKbyteAlign(hBs, hTp->globalFramePos);
1638*e5436536SAndroid Build Coastguard Worker }
1639*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_NOT_ENOUGH_BITS;
1640*e5436536SAndroid Build Coastguard Worker }
1641*e5436536SAndroid Build Coastguard Worker }
1642*e5436536SAndroid Build Coastguard Worker } else {
1643*e5436536SAndroid Build Coastguard Worker /* If bit buffer has not more bits but hTp->numberOfRawDataBlocks > 0
1644*e5436536SAndroid Build Coastguard Worker then too many bits were read and obviously no more RawDataBlocks can
1645*e5436536SAndroid Build Coastguard Worker be read. Set numberOfRawDataBlocks to zero to attempt a new sync
1646*e5436536SAndroid Build Coastguard Worker attempt. */
1647*e5436536SAndroid Build Coastguard Worker if ((INT)FDKgetValidBits(hBs) <= 0) {
1648*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = 0;
1649*e5436536SAndroid Build Coastguard Worker }
1650*e5436536SAndroid Build Coastguard Worker }
1651*e5436536SAndroid Build Coastguard Worker } break;
1652*e5436536SAndroid Build Coastguard Worker default:
1653*e5436536SAndroid Build Coastguard Worker break;
1654*e5436536SAndroid Build Coastguard Worker }
1655*e5436536SAndroid Build Coastguard Worker
1656*e5436536SAndroid Build Coastguard Worker err = transportDec_AdjustEndOfAccessUnit(hTp);
1657*e5436536SAndroid Build Coastguard Worker
1658*e5436536SAndroid Build Coastguard Worker switch (hTp->transportFmt) {
1659*e5436536SAndroid Build Coastguard Worker default:
1660*e5436536SAndroid Build Coastguard Worker break;
1661*e5436536SAndroid Build Coastguard Worker }
1662*e5436536SAndroid Build Coastguard Worker
1663*e5436536SAndroid Build Coastguard Worker return err;
1664*e5436536SAndroid Build Coastguard Worker }
1665*e5436536SAndroid Build Coastguard Worker
transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,const TPDEC_PARAM param,const INT value)1666*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
1667*e5436536SAndroid Build Coastguard Worker const TPDEC_PARAM param,
1668*e5436536SAndroid Build Coastguard Worker const INT value) {
1669*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
1670*e5436536SAndroid Build Coastguard Worker
1671*e5436536SAndroid Build Coastguard Worker if (hTp == NULL) {
1672*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_INVALID_PARAMETER;
1673*e5436536SAndroid Build Coastguard Worker }
1674*e5436536SAndroid Build Coastguard Worker
1675*e5436536SAndroid Build Coastguard Worker switch (param) {
1676*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_MINIMIZE_DELAY:
1677*e5436536SAndroid Build Coastguard Worker if (value) {
1678*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_MINIMIZE_DELAY;
1679*e5436536SAndroid Build Coastguard Worker } else {
1680*e5436536SAndroid Build Coastguard Worker hTp->flags &= ~TPDEC_MINIMIZE_DELAY;
1681*e5436536SAndroid Build Coastguard Worker }
1682*e5436536SAndroid Build Coastguard Worker break;
1683*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_EARLY_CONFIG:
1684*e5436536SAndroid Build Coastguard Worker if (value) {
1685*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_EARLY_CONFIG;
1686*e5436536SAndroid Build Coastguard Worker } else {
1687*e5436536SAndroid Build Coastguard Worker hTp->flags &= ~TPDEC_EARLY_CONFIG;
1688*e5436536SAndroid Build Coastguard Worker }
1689*e5436536SAndroid Build Coastguard Worker break;
1690*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_IGNORE_BUFFERFULLNESS:
1691*e5436536SAndroid Build Coastguard Worker if (value) {
1692*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_IGNORE_BUFFERFULLNESS;
1693*e5436536SAndroid Build Coastguard Worker } else {
1694*e5436536SAndroid Build Coastguard Worker hTp->flags &= ~TPDEC_IGNORE_BUFFERFULLNESS;
1695*e5436536SAndroid Build Coastguard Worker }
1696*e5436536SAndroid Build Coastguard Worker break;
1697*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_SET_BITRATE:
1698*e5436536SAndroid Build Coastguard Worker hTp->avgBitRate = value;
1699*e5436536SAndroid Build Coastguard Worker break;
1700*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_BURST_PERIOD:
1701*e5436536SAndroid Build Coastguard Worker hTp->burstPeriod = value;
1702*e5436536SAndroid Build Coastguard Worker break;
1703*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_RESET: {
1704*e5436536SAndroid Build Coastguard Worker int i;
1705*e5436536SAndroid Build Coastguard Worker
1706*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (1 * 1); i++) {
1707*e5436536SAndroid Build Coastguard Worker FDKresetBitbuffer(&hTp->bitStream[i]);
1708*e5436536SAndroid Build Coastguard Worker hTp->auLength[i] = 0;
1709*e5436536SAndroid Build Coastguard Worker hTp->accessUnitAnchor[i] = 0;
1710*e5436536SAndroid Build Coastguard Worker }
1711*e5436536SAndroid Build Coastguard Worker hTp->flags &= ~(TPDEC_SYNCOK | TPDEC_LOST_FRAMES_PENDING);
1712*e5436536SAndroid Build Coastguard Worker if (hTp->transportFmt != TT_MP4_ADIF) {
1713*e5436536SAndroid Build Coastguard Worker hTp->flags &= ~TPDEC_CONFIG_FOUND;
1714*e5436536SAndroid Build Coastguard Worker }
1715*e5436536SAndroid Build Coastguard Worker hTp->remainder = 0;
1716*e5436536SAndroid Build Coastguard Worker hTp->avgBitRate = 0;
1717*e5436536SAndroid Build Coastguard Worker hTp->missingAccessUnits = 0;
1718*e5436536SAndroid Build Coastguard Worker hTp->numberOfRawDataBlocks = 0;
1719*e5436536SAndroid Build Coastguard Worker hTp->globalFramePos = 0;
1720*e5436536SAndroid Build Coastguard Worker hTp->holdOffFrames = 0;
1721*e5436536SAndroid Build Coastguard Worker } break;
1722*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_TARGETLAYOUT:
1723*e5436536SAndroid Build Coastguard Worker hTp->targetLayout = value;
1724*e5436536SAndroid Build Coastguard Worker break;
1725*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_FORCE_CONFIG_CHANGE:
1726*e5436536SAndroid Build Coastguard Worker hTp->ctrlCFGChange[value].forceCfgChange = TPDEC_FORCE_CONFIG_CHANGE;
1727*e5436536SAndroid Build Coastguard Worker break;
1728*e5436536SAndroid Build Coastguard Worker case TPDEC_PARAM_USE_ELEM_SKIPPING:
1729*e5436536SAndroid Build Coastguard Worker if (value) {
1730*e5436536SAndroid Build Coastguard Worker hTp->flags |= TPDEC_USE_ELEM_SKIPPING;
1731*e5436536SAndroid Build Coastguard Worker } else {
1732*e5436536SAndroid Build Coastguard Worker hTp->flags &= ~TPDEC_USE_ELEM_SKIPPING;
1733*e5436536SAndroid Build Coastguard Worker }
1734*e5436536SAndroid Build Coastguard Worker break;
1735*e5436536SAndroid Build Coastguard Worker }
1736*e5436536SAndroid Build Coastguard Worker
1737*e5436536SAndroid Build Coastguard Worker return error;
1738*e5436536SAndroid Build Coastguard Worker }
1739*e5436536SAndroid Build Coastguard Worker
transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp)1740*e5436536SAndroid Build Coastguard Worker UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) {
1741*e5436536SAndroid Build Coastguard Worker UINT nSubFrames = 0;
1742*e5436536SAndroid Build Coastguard Worker
1743*e5436536SAndroid Build Coastguard Worker if (hTp == NULL) return 0;
1744*e5436536SAndroid Build Coastguard Worker
1745*e5436536SAndroid Build Coastguard Worker if (hTp->transportFmt == TT_MP4_LATM_MCP1 ||
1746*e5436536SAndroid Build Coastguard Worker hTp->transportFmt == TT_MP4_LATM_MCP0 || hTp->transportFmt == TT_MP4_LOAS)
1747*e5436536SAndroid Build Coastguard Worker nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
1748*e5436536SAndroid Build Coastguard Worker else if (hTp->transportFmt == TT_MP4_ADTS)
1749*e5436536SAndroid Build Coastguard Worker nSubFrames = hTp->parser.adts.bs.num_raw_blocks;
1750*e5436536SAndroid Build Coastguard Worker
1751*e5436536SAndroid Build Coastguard Worker return nSubFrames;
1752*e5436536SAndroid Build Coastguard Worker }
1753*e5436536SAndroid Build Coastguard Worker
transportDec_Close(HANDLE_TRANSPORTDEC * phTp)1754*e5436536SAndroid Build Coastguard Worker void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) {
1755*e5436536SAndroid Build Coastguard Worker if (phTp != NULL) {
1756*e5436536SAndroid Build Coastguard Worker if (*phTp != NULL) {
1757*e5436536SAndroid Build Coastguard Worker FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
1758*e5436536SAndroid Build Coastguard Worker FreeRam_TransportDecoder(phTp);
1759*e5436536SAndroid Build Coastguard Worker }
1760*e5436536SAndroid Build Coastguard Worker }
1761*e5436536SAndroid Build Coastguard Worker }
1762*e5436536SAndroid Build Coastguard Worker
transportDec_GetLibInfo(LIB_INFO * info)1763*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
1764*e5436536SAndroid Build Coastguard Worker int i;
1765*e5436536SAndroid Build Coastguard Worker
1766*e5436536SAndroid Build Coastguard Worker if (info == NULL) {
1767*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_UNKOWN_ERROR;
1768*e5436536SAndroid Build Coastguard Worker }
1769*e5436536SAndroid Build Coastguard Worker
1770*e5436536SAndroid Build Coastguard Worker /* search for next free tab */
1771*e5436536SAndroid Build Coastguard Worker for (i = 0; i < FDK_MODULE_LAST; i++) {
1772*e5436536SAndroid Build Coastguard Worker if (info[i].module_id == FDK_NONE) break;
1773*e5436536SAndroid Build Coastguard Worker }
1774*e5436536SAndroid Build Coastguard Worker if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR;
1775*e5436536SAndroid Build Coastguard Worker info += i;
1776*e5436536SAndroid Build Coastguard Worker
1777*e5436536SAndroid Build Coastguard Worker info->module_id = FDK_TPDEC;
1778*e5436536SAndroid Build Coastguard Worker #ifdef SUPPRESS_BUILD_DATE_INFO
1779*e5436536SAndroid Build Coastguard Worker info->build_date = "";
1780*e5436536SAndroid Build Coastguard Worker info->build_time = "";
1781*e5436536SAndroid Build Coastguard Worker #else
1782*e5436536SAndroid Build Coastguard Worker info->build_date = __DATE__;
1783*e5436536SAndroid Build Coastguard Worker info->build_time = __TIME__;
1784*e5436536SAndroid Build Coastguard Worker #endif
1785*e5436536SAndroid Build Coastguard Worker info->title = TP_LIB_TITLE;
1786*e5436536SAndroid Build Coastguard Worker info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
1787*e5436536SAndroid Build Coastguard Worker LIB_VERSION_STRING(info);
1788*e5436536SAndroid Build Coastguard Worker info->flags = 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS |
1789*e5436536SAndroid Build Coastguard Worker CAPF_RAWPACKETS | CAPF_DRM;
1790*e5436536SAndroid Build Coastguard Worker
1791*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
1792*e5436536SAndroid Build Coastguard Worker }
1793*e5436536SAndroid Build Coastguard Worker
transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp,INT mBits)1794*e5436536SAndroid Build Coastguard Worker int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) {
1795*e5436536SAndroid Build Coastguard Worker switch (pTp->transportFmt) {
1796*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
1797*e5436536SAndroid Build Coastguard Worker return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
1798*e5436536SAndroid Build Coastguard Worker case TT_DRM:
1799*e5436536SAndroid Build Coastguard Worker return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
1800*e5436536SAndroid Build Coastguard Worker default:
1801*e5436536SAndroid Build Coastguard Worker return -1;
1802*e5436536SAndroid Build Coastguard Worker }
1803*e5436536SAndroid Build Coastguard Worker }
1804*e5436536SAndroid Build Coastguard Worker
transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp,INT reg)1805*e5436536SAndroid Build Coastguard Worker void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) {
1806*e5436536SAndroid Build Coastguard Worker switch (pTp->transportFmt) {
1807*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
1808*e5436536SAndroid Build Coastguard Worker adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
1809*e5436536SAndroid Build Coastguard Worker break;
1810*e5436536SAndroid Build Coastguard Worker case TT_DRM:
1811*e5436536SAndroid Build Coastguard Worker drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
1812*e5436536SAndroid Build Coastguard Worker break;
1813*e5436536SAndroid Build Coastguard Worker default:
1814*e5436536SAndroid Build Coastguard Worker break;
1815*e5436536SAndroid Build Coastguard Worker }
1816*e5436536SAndroid Build Coastguard Worker }
1817*e5436536SAndroid Build Coastguard Worker
transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)1818*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) {
1819*e5436536SAndroid Build Coastguard Worker switch (pTp->transportFmt) {
1820*e5436536SAndroid Build Coastguard Worker case TT_MP4_ADTS:
1821*e5436536SAndroid Build Coastguard Worker if ((pTp->parser.adts.bs.num_raw_blocks > 0) &&
1822*e5436536SAndroid Build Coastguard Worker (pTp->parser.adts.bs.protection_absent == 0)) {
1823*e5436536SAndroid Build Coastguard Worker transportDec_AdjustEndOfAccessUnit(pTp);
1824*e5436536SAndroid Build Coastguard Worker }
1825*e5436536SAndroid Build Coastguard Worker return adtsRead_CrcCheck(&pTp->parser.adts);
1826*e5436536SAndroid Build Coastguard Worker case TT_DRM:
1827*e5436536SAndroid Build Coastguard Worker return drmRead_CrcCheck(&pTp->parser.drm);
1828*e5436536SAndroid Build Coastguard Worker default:
1829*e5436536SAndroid Build Coastguard Worker return TRANSPORTDEC_OK;
1830*e5436536SAndroid Build Coastguard Worker }
1831*e5436536SAndroid Build Coastguard Worker }
1832*e5436536SAndroid Build Coastguard Worker
transportDec_DrmRawSdcAudioConfig_Check(UCHAR * conf,const UINT length)1833*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
1834*e5436536SAndroid Build Coastguard Worker const UINT length) {
1835*e5436536SAndroid Build Coastguard Worker CSAudioSpecificConfig asc;
1836*e5436536SAndroid Build Coastguard Worker FDK_BITSTREAM bs;
1837*e5436536SAndroid Build Coastguard Worker HANDLE_FDK_BITSTREAM hBs = &bs;
1838*e5436536SAndroid Build Coastguard Worker
1839*e5436536SAndroid Build Coastguard Worker FDKinitBitStream(hBs, conf, BUFSIZE_DUMMY_VALUE, length << 3, BS_READER);
1840*e5436536SAndroid Build Coastguard Worker
1841*e5436536SAndroid Build Coastguard Worker TRANSPORTDEC_ERROR err =
1842*e5436536SAndroid Build Coastguard Worker DrmRawSdcAudioConfig_Parse(&asc, hBs, NULL, (UCHAR)AC_CM_ALLOC_MEM, 0);
1843*e5436536SAndroid Build Coastguard Worker
1844*e5436536SAndroid Build Coastguard Worker return err;
1845*e5436536SAndroid Build Coastguard Worker }
1846