Coverage Report

Created: 2025-10-10 07:00

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