Coverage Report

Created: 2026-04-12 06:21

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