Coverage Report

Created: 2025-11-24 06:13

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
2.32M
#define TPDEC_SYNCOK 1
174
429k
#define TPDEC_MINIMIZE_DELAY 2
175
859k
#define TPDEC_IGNORE_BUFFERFULLNESS 4
176
429k
#define TPDEC_EARLY_CONFIG 8
177
1.28M
#define TPDEC_LOST_FRAMES_PENDING 16
178
852k
#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
56.6k
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
56.6k
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
28.3k
                                      const UINT flags, const UINT nrOfLayers) {
193
28.3k
  HANDLE_TRANSPORTDEC hInput;
194
195
28.3k
  hInput = GetRam_TransportDecoder(0);
196
28.3k
  if (hInput == NULL) {
197
0
    return NULL;
198
0
  }
199
200
  /* Init transportDec struct. */
201
28.3k
  hInput->transportFmt = transportFmt;
202
203
28.3k
  switch (transportFmt) {
204
0
    case TT_MP4_ADIF:
205
0
      break;
206
207
0
    case TT_MP4_ADTS:
208
0
      if (flags & TP_FLAG_MPEG4)
209
0
        hInput->parser.adts.decoderCanDoMpeg4 = 1;
210
0
      else
211
0
        hInput->parser.adts.decoderCanDoMpeg4 = 0;
212
0
      adtsRead_CrcInit(&hInput->parser.adts);
213
0
      hInput->parser.adts.BufferFullnesStartFlag = 1;
214
0
      hInput->numberOfRawDataBlocks = 0;
215
0
      break;
216
217
0
    case TT_DRM:
218
0
      drmRead_CrcInit(&hInput->parser.drm);
219
0
      break;
220
221
0
    case TT_MP4_LATM_MCP0:
222
0
    case TT_MP4_LATM_MCP1:
223
0
      hInput->parser.latm.usacExplicitCfgChanged = 0;
224
0
      hInput->parser.latm.applyAsc = 1;
225
0
      break;
226
28.3k
    case TT_MP4_LOAS:
227
28.3k
      hInput->parser.latm.usacExplicitCfgChanged = 0;
228
28.3k
      hInput->parser.latm.applyAsc = 1;
229
28.3k
      break;
230
0
    case TT_MP4_RAW:
231
0
      break;
232
233
0
    default:
234
0
      FreeRam_TransportDecoder(&hInput);
235
0
      hInput = NULL;
236
0
      break;
237
28.3k
  }
238
239
28.3k
  if (hInput != NULL) {
240
    /* Create bitstream */
241
28.3k
    {
242
28.3k
      hInput->bsBuffer = GetRam_TransportDecoderBuffer(0);
243
28.3k
      if (hInput->bsBuffer == NULL) {
244
0
        transportDec_Close(&hInput);
245
0
        return NULL;
246
0
      }
247
28.3k
      if (nrOfLayers > 1) {
248
0
        transportDec_Close(&hInput);
249
0
        return NULL;
250
0
      }
251
56.6k
      for (UINT i = 0; i < nrOfLayers; i++) {
252
28.3k
        FDKinitBitStream(&hInput->bitStream[i], hInput->bsBuffer, (8192 * 4), 0,
253
28.3k
                         BS_READER);
254
28.3k
      }
255
28.3k
    }
256
0
    hInput->burstPeriod = 0;
257
28.3k
  }
258
259
28.3k
  return hInput;
260
28.3k
}
261
262
TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,
263
                                                UCHAR *conf, const UINT length,
264
0
                                                UINT layer) {
265
0
  int i;
266
267
0
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
268
269
0
  FDK_BITSTREAM bs;
270
0
  HANDLE_FDK_BITSTREAM hBs = &bs;
271
272
0
  int fConfigFound = 0;
273
274
0
  UCHAR configChanged = 0;
275
0
  UCHAR configMode = AC_CM_DET_CFG_CHANGE;
276
277
0
  UCHAR tmpConf[1024] = {0};
278
0
  if (length > 1024) {
279
0
    return TRANSPORTDEC_UNSUPPORTED_FORMAT;
280
0
  }
281
0
  FDKmemcpy(tmpConf, conf, length);
282
0
  FDKinitBitStream(hBs, tmpConf, 1024, length << 3, BS_READER);
283
284
0
  for (i = 0; i < 2; i++) {
285
0
    if (i > 0) {
286
0
      FDKpushBack(hBs, (INT)length * 8 - (INT)FDKgetValidBits(hBs));
287
0
      configMode = AC_CM_ALLOC_MEM;
288
0
    }
289
290
    /* config transport decoder */
291
0
    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
0
      default:
307
0
        fConfigFound = 1;
308
0
        err = AudioSpecificConfig_Parse(&hTp->asc[(1 * 1)], hBs, 1,
309
0
                                        &hTp->callbacks, configMode,
310
0
                                        configChanged, AOT_NULL_OBJECT);
311
0
        if (err == TRANSPORTDEC_OK) {
312
0
          int errC;
313
314
0
          hTp->asc[layer] = hTp->asc[(1 * 1)];
315
0
          errC = hTp->callbacks.cbUpdateConfig(
316
0
              hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
317
0
              hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
318
0
          if (errC != 0) {
319
0
            err = TRANSPORTDEC_PARSE_ERROR;
320
0
          }
321
0
        }
322
0
        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
0
    }
339
340
0
    if (err == TRANSPORTDEC_OK) {
341
0
      if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
342
0
                       hTp->asc[layer].SbrConfigChanged ||
343
0
                       hTp->asc[layer].SacConfigChanged)) {
344
0
        int errC;
345
346
0
        configChanged = 1;
347
0
        errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
348
0
                                        &hTp->asc[layer]);
349
0
        if (errC != 0) {
350
0
          err = TRANSPORTDEC_PARSE_ERROR;
351
0
        }
352
0
      }
353
0
    }
354
355
    /* if an error is detected terminate config parsing to avoid that an invalid
356
     * config is accepted in the second pass */
357
0
    if (err != TRANSPORTDEC_OK) {
358
0
      break;
359
0
    }
360
0
  }
361
362
0
  if (err == TRANSPORTDEC_OK && fConfigFound) {
363
0
    hTp->flags |= TPDEC_CONFIG_FOUND;
364
0
  }
365
366
0
  return err;
367
0
}
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
96
                                             UCHAR *implicitExplicitCfgDiff) {
375
96
  int errC;
376
96
  FDK_BITSTREAM bs;
377
96
  HANDLE_FDK_BITSTREAM hBs = &bs;
378
96
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
379
96
  int fConfigFound = 0;
380
96
  UCHAR configMode = AC_CM_ALLOC_MEM;
381
96
  *implicitExplicitCfgDiff = 0;
382
383
96
  FDK_ASSERT(hTp->asc->m_aot == AOT_USAC);
384
385
96
  FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3,
386
96
                   BS_READER);
387
388
96
  if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
389
67
      (hTp->ctrlCFGChange[layer].buildUpStatus !=
390
67
       TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
391
67
    if (hTp->asc->m_aot == AOT_USAC) {
392
67
      if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 ==
393
67
          newConfigLength) {
394
44
        if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig,
395
44
                           newConfigLength)) {
396
35
          if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from
397
                                                            LOAS/LATM parser */
398
29
            hTp->parser.latm.usacExplicitCfgChanged = 0;
399
29
            hTp->ctrlCFGChange[layer].flushCnt = 0;
400
29
            hTp->ctrlCFGChange[layer].flushStatus =
401
29
                TPDEC_USAC_DASH_IPF_FLUSH_ON;
402
29
            hTp->ctrlCFGChange[layer].buildUpCnt = 0;
403
29
            hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
404
29
          } else {
405
6
            *configChanged = 0;
406
6
            return err;
407
6
          }
408
35
        } else {
409
9
          *implicitExplicitCfgDiff = 1;
410
9
        }
411
44
      } 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
61
      if (*implicitExplicitCfgDiff) {
417
32
        switch (hTp->transportFmt) {
418
0
          case TT_MP4_LATM_MCP0:
419
0
          case TT_MP4_LATM_MCP1:
420
32
          case TT_MP4_LOAS:
421
            /* reset decoder to initial state to achieve definite behavior after
422
             * error in config */
423
32
            hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
424
32
                                     &hTp->asc[layer]);
425
32
            hTp->parser.latm.usacExplicitCfgChanged = 0;
426
32
            hTp->parser.latm.applyAsc = 1;
427
32
            err = TRANSPORTDEC_PARSE_ERROR;
428
32
            goto bail;
429
0
          default:
430
0
            break;
431
32
        }
432
32
      }
433
61
    }
434
67
  }
435
436
58
  {
437
58
    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
58
    if ((hTp->ctrlCFGChange[layer].flushStatus ==
449
58
         TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
450
58
        (hTp->ctrlCFGChange[layer].flushStatus ==
451
58
         TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
452
58
      SCHAR counter = 0;
453
58
      if (hTp->asc->m_aot == AOT_USAC) {
454
58
        counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES;
455
58
      }
456
58
      if (hTp->ctrlCFGChange[layer].flushCnt >= counter) {
457
29
        hTp->ctrlCFGChange[layer].flushCnt = 0;
458
29
        hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
459
29
        hTp->ctrlCFGChange[layer].forceCfgChange = 0;
460
29
        if (hTp->asc->m_aot == AOT_USAC) {
461
29
          hTp->ctrlCFGChange[layer].buildUpCnt =
462
29
              TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1;
463
29
          hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON;
464
29
        }
465
29
      }
466
467
      /* Activate flush mode. After that continue with build up mode in core */
468
58
      if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
469
58
                                         &hTp->ctrlCFGChange[layer]) != 0) {
470
0
        err = TRANSPORTDEC_PARSE_ERROR;
471
0
      }
472
473
58
      if ((hTp->ctrlCFGChange[layer].flushStatus ==
474
58
           TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
475
58
          (hTp->ctrlCFGChange[layer].flushStatus ==
476
58
           TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
477
29
        hTp->ctrlCFGChange[layer].flushCnt++;
478
29
        return err;
479
29
      }
480
58
    }
481
482
29
    if (hTp->asc->m_aot == AOT_USAC) {
483
29
      fConfigFound = 1;
484
485
29
      if (err == TRANSPORTDEC_OK) {
486
29
        *configChanged = 0;
487
29
        configMode = AC_CM_DET_CFG_CHANGE;
488
489
87
        for (int i = 0; i < 2; i++) {
490
58
          if (i > 0) {
491
29
            FDKpushBack(hBs,
492
29
                        (INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs));
493
29
            configMode = AC_CM_ALLOC_MEM;
494
29
          }
495
          /* config transport decoder */
496
58
          err = AudioSpecificConfig_Parse(
497
58
              &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode,
498
58
              *configChanged, hTp->asc[layer].m_aot);
499
58
          if (err == TRANSPORTDEC_OK) {
500
58
            hTp->asc[layer] = hTp->asc[(1 * 1)];
501
58
            errC = hTp->callbacks.cbUpdateConfig(
502
58
                hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
503
58
                hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
504
58
            if (errC != 0) {
505
0
              err = TRANSPORTDEC_PARSE_ERROR;
506
0
            }
507
58
          }
508
509
58
          if (err == TRANSPORTDEC_OK) {
510
58
            if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
511
26
                             hTp->asc[layer].SbrConfigChanged ||
512
25
                             hTp->asc[layer].SacConfigChanged)) {
513
4
              *configChanged = 1;
514
4
              errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
515
4
                                              &hTp->asc[layer]);
516
4
              if (errC != 0) {
517
0
                err = TRANSPORTDEC_PARSE_ERROR;
518
0
              }
519
4
            }
520
58
          }
521
522
          /* if an error is detected terminate config parsing to avoid that an
523
           * invalid config is accepted in the second pass */
524
58
          if (err != TRANSPORTDEC_OK) {
525
0
            break;
526
0
          }
527
58
        }
528
29
      }
529
29
    }
530
531
61
  bail:
532
    /* save new config */
533
61
    if (err == TRANSPORTDEC_OK) {
534
29
      if (hTp->asc->m_aot == AOT_USAC) {
535
29
        hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3;
536
29
        FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig,
537
29
                  newConfigLength);
538
        /* in case of USAC reset transportDecoder variables here because
539
         * otherwise without IPF they are not reset */
540
29
        hTp->ctrlCFGChange[layer].flushCnt = 0;
541
29
        hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
542
29
        hTp->ctrlCFGChange[layer].buildUpCnt = 0;
543
29
        hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
544
29
      }
545
32
    } else {
546
32
      hTp->numberOfRawDataBlocks = 0;
547
548
      /* If parsing error while config found, clear ctrlCFGChange-struct */
549
32
      hTp->ctrlCFGChange[layer].flushCnt = 0;
550
32
      hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
551
32
      hTp->ctrlCFGChange[layer].buildUpCnt = 0;
552
32
      hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
553
32
      hTp->ctrlCFGChange[layer].cfgChanged = 0;
554
32
      hTp->ctrlCFGChange[layer].contentChanged = 0;
555
32
      hTp->ctrlCFGChange[layer].forceCfgChange = 0;
556
557
32
      hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
558
32
                                     &hTp->ctrlCFGChange[layer]);
559
32
    }
560
61
  }
561
562
61
  if (err == TRANSPORTDEC_OK && fConfigFound) {
563
29
    hTp->flags |= TPDEC_CONFIG_FOUND;
564
29
  }
565
566
61
  return err;
567
29
}
568
569
int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,
570
                                     const cbUpdateConfig_t cbUpdateConfig,
571
28.3k
                                     void *user_data) {
572
28.3k
  if (hTpDec == NULL) {
573
0
    return -1;
574
0
  }
575
28.3k
  hTpDec->callbacks.cbUpdateConfig = cbUpdateConfig;
576
28.3k
  hTpDec->callbacks.cbUpdateConfigData = user_data;
577
28.3k
  return 0;
578
28.3k
}
579
580
int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,
581
                                         const cbFreeMem_t cbFreeMem,
582
28.3k
                                         void *user_data) {
583
28.3k
  if (hTpDec == NULL) {
584
0
    return -1;
585
0
  }
586
28.3k
  hTpDec->callbacks.cbFreeMem = cbFreeMem;
587
28.3k
  hTpDec->callbacks.cbFreeMemData = user_data;
588
28.3k
  return 0;
589
28.3k
}
590
591
int transportDec_RegisterCtrlCFGChangeCallback(
592
    HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange,
593
28.3k
    void *user_data) {
594
28.3k
  if (hTpDec == NULL) {
595
0
    return -1;
596
0
  }
597
28.3k
  hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange;
598
28.3k
  hTpDec->callbacks.cbCtrlCFGChangeData = user_data;
599
28.3k
  return 0;
600
28.3k
}
601
602
int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,
603
28.3k
                                     const cbSsc_t cbSsc, void *user_data) {
604
28.3k
  if (hTpDec == NULL) {
605
0
    return -1;
606
0
  }
607
28.3k
  hTpDec->callbacks.cbSsc = cbSsc;
608
28.3k
  hTpDec->callbacks.cbSscData = user_data;
609
28.3k
  return 0;
610
28.3k
}
611
612
int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
613
28.3k
                                     const cbSbr_t cbSbr, void *user_data) {
614
28.3k
  if (hTpDec == NULL) {
615
0
    return -1;
616
0
  }
617
28.3k
  hTpDec->callbacks.cbSbr = cbSbr;
618
28.3k
  hTpDec->callbacks.cbSbrData = user_data;
619
28.3k
  return 0;
620
28.3k
}
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
28.3k
                                              UINT *pLoudnessInfoSetPosition) {
636
28.3k
  if (hTpDec == NULL) {
637
0
    return -1;
638
0
  }
639
640
28.3k
  hTpDec->callbacks.cbUniDrc = cbUniDrc;
641
28.3k
  hTpDec->callbacks.cbUniDrcData = user_data;
642
643
28.3k
  hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition;
644
28.3k
  return 0;
645
28.3k
}
646
647
TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
648
                                         UCHAR *pBuffer, const UINT bufferSize,
649
28.9k
                                         UINT *pBytesValid, const INT layer) {
650
28.9k
  HANDLE_FDK_BITSTREAM hBs;
651
652
28.9k
  if ((hTp == NULL) || (layer >= 1)) {
653
0
    return TRANSPORTDEC_INVALID_PARAMETER;
654
0
  }
655
656
  /* set bitbuffer shortcut */
657
28.9k
  hBs = &hTp->bitStream[layer];
658
659
28.9k
  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
28.9k
  } else {
668
    /* ... else feed bitbuffer with new stream data (append). */
669
670
28.9k
    if (*pBytesValid == 0) {
671
      /* nothing to do */
672
0
      return TRANSPORTDEC_OK;
673
28.9k
    } else {
674
28.9k
      const int bytesValid = *pBytesValid;
675
28.9k
      FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
676
677
28.9k
      if (hTp->numberOfRawDataBlocks > 0) {
678
0
        hTp->globalFramePos += (bytesValid - *pBytesValid) * 8;
679
0
        hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
680
0
      }
681
28.9k
    }
682
28.9k
  }
683
684
28.9k
  return TRANSPORTDEC_OK;
685
28.9k
}
686
687
HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
688
1.27M
                                               const UINT layer) {
689
1.27M
  return &hTp->bitStream[layer];
690
1.27M
}
691
692
194
TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) {
693
194
  return hTp->transportFmt;
694
194
}
695
696
20.8k
INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) {
697
20.8k
  INT bufferFullness = -1;
698
699
20.8k
  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
20.8k
    case TT_MP4_LOAS:
709
20.8k
    case TT_MP4_LATM_MCP0:
710
20.8k
    case TT_MP4_LATM_MCP1:
711
20.8k
      if (hTp->parser.latm.m_linfo[0][0].m_bufferFullness != 0xff) {
712
20.3k
        bufferFullness = hTp->parser.latm.m_linfo[0][0].m_bufferFullness;
713
20.3k
      }
714
20.8k
      break;
715
0
    default:
716
0
      break;
717
20.8k
  }
718
719
20.8k
  return bufferFullness;
720
20.8k
}
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
412k
    HANDLE_TRANSPORTDEC hTp) {
729
412k
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
730
412k
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
731
732
412k
  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
412k
    case TT_MP4_LOAS:
739
412k
    case TT_MP4_LATM_MCP0:
740
412k
    case TT_MP4_LATM_MCP1:
741
412k
      if (hTp->numberOfRawDataBlocks == 0) {
742
        /* Do byte align at the end of AudioMuxElement. */
743
111k
        FDKbyteAlign(hBs, hTp->globalFramePos);
744
745
        /* Check global frame length */
746
111k
        if (hTp->transportFmt == TT_MP4_LOAS &&
747
111k
            hTp->parser.latm.m_audioMuxLengthBytes > 0) {
748
111k
          int loasOffset;
749
750
111k
          loasOffset = ((INT)hTp->parser.latm.m_audioMuxLengthBytes * 8 +
751
111k
                        (INT)FDKgetValidBits(hBs)) -
752
111k
                       (INT)hTp->globalFramePos;
753
111k
          if (loasOffset != 0) {
754
109k
            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
109k
            if (loasOffset < 0) {
759
109k
              err = TRANSPORTDEC_PARSE_ERROR;
760
109k
            }
761
109k
          }
762
111k
        }
763
111k
      }
764
412k
      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
412k
  }
805
806
412k
  return err;
807
412k
}
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
20.8k
                                                  INT bitsAvail) {
823
20.8k
  INT checkLengthBits, avgBitsPerFrame;
824
20.8k
  INT maxAU; /* maximum number of frames per Master Frame */
825
20.8k
  INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
826
20.8k
  INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;
827
828
20.8k
  if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) {
829
20.8k
    return TRANSPORTDEC_OK;
830
20.8k
  }
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
873k
    int *pHeaderBits) {
876
873k
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
877
873k
  int rawDataBlockLength = *pRawDataBlockLength;
878
873k
  int fTraverseMoreFrames =
879
873k
      (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
880
873k
  int syncLayerFrameBits =
881
873k
      (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
882
873k
  int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
883
873k
  int startPos;
884
885
873k
  startPos = (INT)FDKgetValidBits(hBs);
886
887
873k
  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
873k
    case TT_MP4_LOAS:
970
873k
      if (hTp->numberOfRawDataBlocks <= 0) {
971
575k
        syncLayerFrameBits = (INT)FDKreadBits(hBs, 13);
972
575k
        hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
973
575k
        syncLayerFrameBits <<= 3;
974
575k
      }
975
873k
      FDK_FALLTHROUGH;
976
873k
    case TT_MP4_LATM_MCP1:
977
873k
    case TT_MP4_LATM_MCP0:
978
873k
      if (hTp->numberOfRawDataBlocks <= 0) {
979
575k
        hTp->globalFramePos = FDKgetValidBits(hBs);
980
981
575k
        err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt,
982
575k
                              &hTp->callbacks, hTp->asc, &fConfigFound,
983
575k
                              ignoreBufferFullness);
984
985
575k
        if (err != TRANSPORTDEC_OK) {
986
436k
          if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) &&
987
435k
              !TPDEC_IS_FATAL_ERROR(err)) {
988
435k
            err = TRANSPORTDEC_SYNC_ERROR;
989
435k
          }
990
436k
        } else {
991
139k
          hTp->numberOfRawDataBlocks =
992
139k
              CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
993
139k
          if (hTp->transportFmt == TT_MP4_LOAS) {
994
139k
            syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13);
995
139k
            if (syncLayerFrameBits <= 0) {
996
20.9k
              err = TRANSPORTDEC_SYNC_ERROR;
997
20.9k
            }
998
139k
          }
999
139k
        }
1000
575k
      } else {
1001
298k
        err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
1002
298k
        if (err != TRANSPORTDEC_OK) {
1003
3.72k
          err = TRANSPORTDEC_SYNC_ERROR;
1004
3.72k
        }
1005
298k
      }
1006
873k
      if (err == TRANSPORTDEC_OK) {
1007
412k
        int layer;
1008
412k
        rawDataBlockLength = 0;
1009
412k
        for (layer = 0;
1010
825k
             layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0);
1011
412k
             layer += 1) {
1012
412k
          rawDataBlockLength +=
1013
412k
              CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer);
1014
412k
        }
1015
412k
        hTp->numberOfRawDataBlocks--;
1016
460k
      } else {
1017
460k
        hTp->numberOfRawDataBlocks = 0;
1018
460k
      }
1019
873k
      break;
1020
0
    default: { syncLayerFrameBits = 0; } break;
1021
873k
  }
1022
1023
873k
bail:
1024
1025
873k
  *pRawDataBlockLength = rawDataBlockLength;
1026
1027
873k
  if (pHeaderBits != NULL) {
1028
873k
    *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
1029
873k
  }
1030
1031
1.74M
  for (int i = 0; i < (1 * 1); i++) {
1032
    /* If parsing error while config found, clear ctrlCFGChange-struct */
1033
873k
    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
873k
  }
1047
1048
873k
  if (pfConfigFound != NULL) {
1049
873k
    *pfConfigFound = fConfigFound;
1050
873k
  }
1051
1052
873k
  if (pfTraverseMoreFrames != NULL) {
1053
873k
    *pfTraverseMoreFrames = fTraverseMoreFrames;
1054
873k
  }
1055
873k
  if (pSyncLayerFrameBits != NULL) {
1056
873k
    *pSyncLayerFrameBits = syncLayerFrameBits;
1057
873k
  }
1058
1059
873k
  return err;
1060
873k
}
1061
1062
/* How many bits to advance for synchronization search. */
1063
55.0M
#define TPDEC_SYNCSKIP 8
1064
1065
static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
1066
429k
                                          INT *pHeaderBits) {
1067
429k
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
1068
429k
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
1069
1070
429k
  INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
1071
429k
  INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
1072
429k
  INT totalBits;
1073
429k
  INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
1074
429k
  INT numFramesTraversed = 0, fTraverseMoreFrames,
1075
429k
      fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
1076
429k
  INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious,
1077
429k
      globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
1078
429k
  INT ignoreBufferFullness =
1079
429k
      hTp->flags &
1080
429k
      (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK);
1081
429k
  UINT endTpFrameBitsPrevious = 0;
1082
1083
  /* Synch parameters */
1084
429k
  INT syncLength; /* Length of sync word in bits */
1085
429k
  UINT syncWord;  /* Sync word to be found */
1086
429k
  UINT syncMask;  /* Mask for sync word (for adding one bit, so comprising one
1087
                     bit less) */
1088
429k
  C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);
1089
1090
429k
  totalBits = (INT)FDKgetValidBits(hBs);
1091
1092
429k
  if (totalBits <= 0) {
1093
382
    err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1094
382
    goto bail;
1095
382
  }
1096
1097
429k
  fTraverseMoreFrames =
1098
429k
      (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) &&
1099
0
      !(hTp->flags & TPDEC_SYNCOK);
1100
1101
  /* Set transport specific sync parameters */
1102
429k
  switch (hTp->transportFmt) {
1103
0
    case TT_MP4_ADTS:
1104
0
      syncWord = ADTS_SYNCWORD;
1105
0
      syncLength = ADTS_SYNCLENGTH;
1106
0
      break;
1107
429k
    case TT_MP4_LOAS:
1108
429k
      syncWord = 0x2B7;
1109
429k
      syncLength = 11;
1110
429k
      break;
1111
0
    default:
1112
0
      syncWord = 0;
1113
0
      syncLength = 0;
1114
0
      break;
1115
429k
  }
1116
1117
429k
  syncMask = (1 << syncLength) - 1;
1118
1119
884k
  do {
1120
884k
    INT bitsAvail = 0;   /* Bits available in bitstream buffer    */
1121
884k
    INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries
1122
                          */
1123
884k
    UINT synch;          /* Current sync word read from bitstream */
1124
1125
884k
    headerBitsPrevious = headerBits;
1126
1127
884k
    bitsAvail = (INT)FDKgetValidBits(hBs);
1128
1129
884k
    if (hTp->numberOfRawDataBlocks == 0) {
1130
      /* search synchword */
1131
1132
586k
      FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0);
1133
1134
586k
      if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) {
1135
4.01k
        err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1136
4.01k
        headerBits = 0;
1137
582k
      } else {
1138
582k
        synch = FDKreadBits(hBs, syncLength);
1139
1140
582k
        if (!(hTp->flags & TPDEC_SYNCOK)) {
1141
13.7M
          for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP;
1142
13.7M
               bitsAvail -= TPDEC_SYNCSKIP) {
1143
13.7M
            if (synch == syncWord) {
1144
476k
              break;
1145
476k
            }
1146
13.2M
            synch = ((synch << TPDEC_SYNCSKIP) & syncMask) |
1147
13.2M
                    FDKreadBits(hBs, TPDEC_SYNCSKIP);
1148
13.2M
          }
1149
480k
        }
1150
582k
        if (synch != syncWord) {
1151
          /* No correct syncword found. */
1152
7.46k
          err = TRANSPORTDEC_SYNC_ERROR;
1153
575k
        } else {
1154
575k
          err = TRANSPORTDEC_OK;
1155
575k
        }
1156
582k
        headerBits = syncLength;
1157
582k
      }
1158
586k
    } else {
1159
298k
      headerBits = 0;
1160
298k
    }
1161
1162
    /* Save previous raw data block data */
1163
884k
    rawDataBlockLengthPrevious = rawDataBlockLength;
1164
884k
    numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;
1165
1166
    /* Parse transport header (raw data block granularity) */
1167
1168
884k
    if (err == TRANSPORTDEC_OK) {
1169
873k
      err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness,
1170
873k
                                    &rawDataBlockLength, &fTraverseMoreFrames,
1171
873k
                                    &syncLayerFrameBits, &fConfigFound,
1172
873k
                                    &headerBits);
1173
873k
      if (headerBits > bitsAvail) {
1174
11.6k
        err = (headerBits < (INT)hBs->hBitBuf.bufBits)
1175
11.6k
                  ? TRANSPORTDEC_NOT_ENOUGH_BITS
1176
11.6k
                  : TRANSPORTDEC_SYNC_ERROR;
1177
11.6k
      }
1178
873k
      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
873k
    }
1188
1189
884k
    bitsAvail -= headerBits;
1190
1191
884k
    checkLengthBits = syncLayerFrameBits;
1192
1193
    /* Check if the whole frame would fit the bitstream buffer */
1194
884k
    if (err == TRANSPORTDEC_OK) {
1195
412k
      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
412k
      } else {
1201
412k
        if (bitsAvail < checkLengthBits) {
1202
289
          err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1203
289
        }
1204
412k
      }
1205
412k
    }
1206
1207
884k
    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1208
8.74k
      break;
1209
8.74k
    }
1210
1211
876k
    if (err == TRANSPORTDEC_SYNC_ERROR) {
1212
463k
      int bits;
1213
1214
      /* Enforce re-sync of transport headers. */
1215
463k
      hTp->numberOfRawDataBlocks = 0;
1216
1217
      /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
1218
463k
      bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
1219
      /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
1220
       * next time. */
1221
463k
      FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
1222
463k
      headerBits = 0;
1223
463k
    }
1224
1225
    /* Frame traversal */
1226
876k
    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
876k
  } while (fTraverseMoreFrames ||
1270
876k
           (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
1271
1272
  /* Restore context in case of ECD frame traversal */
1273
429k
  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
429k
  if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
1286
429k
                      TPDEC_SYNCOK)) &&
1287
28.9k
      err == TRANSPORTDEC_OK) {
1288
20.8k
    err =
1289
20.8k
        additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
1290
20.8k
                                (INT)FDKgetValidBits(hBs) - syncLayerFrameBits);
1291
20.8k
    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1292
0
      hTp->holdOffFrames++;
1293
0
    }
1294
20.8k
  }
1295
1296
  /* Rewind for retry because of not enough bits */
1297
429k
  if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
1298
8.74k
    FDKpushBack(hBs, headerBits);
1299
8.74k
    hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
1300
8.74k
    headerBits = 0;
1301
8.74k
    rawDataBlockLength = rawDataBlockLengthPrevious;
1302
420k
  } else {
1303
    /* reset hold off frame counter */
1304
420k
    hTp->holdOffFrames = 0;
1305
420k
  }
1306
1307
  /* Return to last good frame in case of frame traversal but not ECD. */
1308
429k
  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
429k
bail:
1319
429k
  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
429k
  if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&
1325
8.74k
      (FDKgetValidBits(hBs) >=
1326
8.74k
       (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) -
1327
8.74k
        7))) {
1328
0
    FDKpushFor(hBs, TPDEC_SYNCSKIP);
1329
0
    err = TRANSPORTDEC_SYNC_ERROR;
1330
0
  }
1331
1332
429k
  if (err == TRANSPORTDEC_OK) {
1333
412k
    hTp->flags |= TPDEC_SYNCOK;
1334
412k
  }
1335
1336
429k
  if (fConfigFound) {
1337
422k
    hTp->flags |= TPDEC_CONFIG_FOUND;
1338
422k
  }
1339
1340
429k
  if (pHeaderBits != NULL) {
1341
429k
    *pHeaderBits = headerBits;
1342
429k
  }
1343
1344
429k
  if (err == TRANSPORTDEC_SYNC_ERROR) {
1345
8.42k
    hTp->flags &= ~TPDEC_SYNCOK;
1346
8.42k
  }
1347
1348
429k
  C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);
1349
1350
429k
  return err;
1351
429k
}
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
429k
                                                  const UINT layer) {
1359
429k
  TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
1360
429k
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
1361
1362
429k
  INT headerBits;
1363
429k
  INT bitDistance, bfDelta;
1364
1365
  /* Obtain distance to next synch word */
1366
429k
  bitDistance = (INT)FDKgetValidBits(hBs);
1367
429k
  error = synchronization(hTp, &headerBits);
1368
429k
  bitDistance -= (INT)FDKgetValidBits(hBs);
1369
1370
429k
  FDK_ASSERT(bitDistance >= 0);
1371
1372
429k
  INT nAU = -1;
1373
1374
429k
  if (error == TRANSPORTDEC_SYNC_ERROR ||
1375
421k
      (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
1376
    /* Check if estimating lost access units is feasible. */
1377
8.42k
    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
8.42k
  }
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
429k
  if (nAU > 0) {
1449
0
    error = TRANSPORTDEC_SYNC_ERROR;
1450
0
  }
1451
1452
429k
  hTp->missingAccessUnits = nAU;
1453
1454
429k
  return error;
1455
429k
}
1456
1457
/* returns error code */
1458
TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
1459
429k
                                               const UINT layer) {
1460
429k
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1461
429k
  HANDLE_FDK_BITSTREAM hBs;
1462
1463
429k
  if (!hTp) {
1464
0
    return TRANSPORTDEC_INVALID_PARAMETER;
1465
0
  }
1466
1467
429k
  hBs = &hTp->bitStream[layer];
1468
1469
429k
  if ((INT)FDKgetValidBits(hBs) <= 0) {
1470
    /* This is only relevant for RAW and ADIF cases.
1471
     * For streaming formats err will get overwritten. */
1472
382
    err = TRANSPORTDEC_NOT_ENOUGH_BITS;
1473
382
    hTp->numberOfRawDataBlocks = 0;
1474
382
  }
1475
1476
429k
  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
429k
    case TT_MP4_LOAS:
1558
429k
      err = transportDec_readStream(hTp, layer);
1559
429k
      break;
1560
1561
0
    default:
1562
0
      err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
1563
0
      break;
1564
429k
  }
1565
1566
429k
  if (err == TRANSPORTDEC_OK) {
1567
412k
    hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
1568
412k
  } else {
1569
17.5k
    hTp->accessUnitAnchor[layer] = 0;
1570
17.5k
  }
1571
1572
429k
bail:
1573
429k
  return err;
1574
429k
}
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
907k
                                    const UINT layer) {
1592
907k
  INT bits;
1593
1594
907k
  if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
1595
282k
    bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]);
1596
282k
    if (bits >= 0) {
1597
277k
      bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits);
1598
277k
    }
1599
624k
  } else {
1600
624k
    bits = FDKgetValidBits(&hTp->bitStream[layer]);
1601
624k
  }
1602
1603
907k
  return bits;
1604
907k
}
1605
1606
INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
1607
414k
                                const UINT layer) {
1608
414k
  return hTp->auLength[layer];
1609
414k
}
1610
1611
TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
1612
8.42k
    INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) {
1613
8.42k
  *pNAccessUnits = hTp->missingAccessUnits;
1614
1615
8.42k
  return TRANSPORTDEC_OK;
1616
8.42k
}
1617
1618
/* Inform the transportDec layer that reading of access unit has finished. */
1619
412k
TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) {
1620
412k
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
1621
1622
412k
  switch (hTp->transportFmt) {
1623
412k
    case TT_MP4_LOAS:
1624
412k
    case TT_MP4_LATM_MCP0:
1625
412k
    case TT_MP4_LATM_MCP1: {
1626
412k
      HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
1627
412k
      if (hTp->numberOfRawDataBlocks == 0) {
1628
        /* Read other data if available. */
1629
10.0k
        if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) {
1630
2.24k
          int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm);
1631
1632
2.24k
          if ((INT)FDKgetValidBits(hBs) >= otherDataLen) {
1633
2.20k
            FDKpushFor(hBs, otherDataLen);
1634
2.20k
          } else {
1635
            /* Do byte align at the end of AudioMuxElement. */
1636
37
            if (hTp->numberOfRawDataBlocks == 0) {
1637
37
              FDKbyteAlign(hBs, hTp->globalFramePos);
1638
37
            }
1639
37
            return TRANSPORTDEC_NOT_ENOUGH_BITS;
1640
37
          }
1641
2.24k
        }
1642
402k
      } 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
402k
        if ((INT)FDKgetValidBits(hBs) <= 0) {
1648
101k
          hTp->numberOfRawDataBlocks = 0;
1649
101k
        }
1650
402k
      }
1651
412k
    } break;
1652
412k
    default:
1653
0
      break;
1654
412k
  }
1655
1656
412k
  err = transportDec_AdjustEndOfAccessUnit(hTp);
1657
1658
412k
  switch (hTp->transportFmt) {
1659
412k
    default:
1660
412k
      break;
1661
412k
  }
1662
1663
412k
  return err;
1664
412k
}
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
28.3k
void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) {
1755
28.3k
  if (phTp != NULL) {
1756
28.3k
    if (*phTp != NULL) {
1757
28.3k
      FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
1758
28.3k
      FreeRam_TransportDecoder(phTp);
1759
28.3k
    }
1760
28.3k
  }
1761
28.3k
}
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
39.3k
int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) {
1795
39.3k
  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
39.3k
    default:
1801
39.3k
      return -1;
1802
39.3k
  }
1803
39.3k
}
1804
1805
38.9k
void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) {
1806
38.9k
  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
38.9k
    default:
1814
38.9k
      break;
1815
38.9k
  }
1816
38.9k
}
1817
1818
414k
TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) {
1819
414k
  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
414k
    default:
1829
414k
      return TRANSPORTDEC_OK;
1830
414k
  }
1831
414k
}
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
}