Coverage Report

Created: 2025-07-01 06:21

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