aboutsummaryrefslogtreecommitdiffstats
path: root/libMpegTPDec
diff options
context:
space:
mode:
Diffstat (limited to 'libMpegTPDec')
-rw-r--r--libMpegTPDec/include/mpegFileRead.h194
-rw-r--r--libMpegTPDec/include/tp_data.h487
-rw-r--r--libMpegTPDec/include/tpdec_lib.h621
-rw-r--r--libMpegTPDec/src/mpegFileFormat.h114
-rw-r--r--libMpegTPDec/src/tp_version.h118
-rw-r--r--libMpegTPDec/src/tpdec_adif.cpp163
-rw-r--r--libMpegTPDec/src/tpdec_adif.h143
-rw-r--r--libMpegTPDec/src/tpdec_adts.cpp352
-rw-r--r--libMpegTPDec/src/tpdec_adts.h200
-rw-r--r--libMpegTPDec/src/tpdec_asc.cpp2681
-rw-r--r--libMpegTPDec/src/tpdec_drm.cpp154
-rw-r--r--libMpegTPDec/src/tpdec_drm.h182
-rw-r--r--libMpegTPDec/src/tpdec_latm.cpp693
-rw-r--r--libMpegTPDec/src/tpdec_latm.h197
-rw-r--r--libMpegTPDec/src/tpdec_lib.cpp1501
-rw-r--r--libMpegTPDec/src/version13
16 files changed, 4809 insertions, 3004 deletions
diff --git a/libMpegTPDec/include/mpegFileRead.h b/libMpegTPDec/include/mpegFileRead.h
deleted file mode 100644
index 1fbfb58..0000000
--- a/libMpegTPDec/include/mpegFileRead.h
+++ /dev/null
@@ -1,194 +0,0 @@
-
-/* -----------------------------------------------------------------------------------------------------------
-Software License for The Fraunhofer FDK AAC Codec Library for Android
-
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
-
- 1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
-
-2. COPYRIGHT LICENSE
-
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
-
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
-
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
-modifications thereto to recipients of copies in binary form.
-
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
-
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
-
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
-
-3. NO PATENT LICENSE
-
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
-
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
-
-4. DISCLAIMER
-
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
-
-5. CONTACT INFORMATION
-
-Fraunhofer Institute for Integrated Circuits IIS
-Attention: Audio and Multimedia Departments - FDK AAC LL
-Am Wolfsmantel 33
-91058 Erlangen, Germany
-
-www.iis.fraunhofer.de/amm
-amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
-
-/***************************** MPEG-4 AAC Decoder **************************
-
- Author(s): Manuel Jander
- Description: Bitstream data provider for MP4 decoders
-
-******************************************************************************/
-
-#include "machine_type.h"
-#include "FDK_audio.h"
-
-#define MPFREAD_MP4FF_DISABLE
-
-#ifndef MPFREAD_MP4FF_DISABLE
- /*!< If MPFREAD_MP4FF_ENABLE is set, include support for MPEG ISO fileformat.
- If not set, no .mp4, .m4a and .3gp files can be used for input. */
- #define MPFREAD_MP4FF_ENABLE
-#endif
-
-/* maximum number of layers which can be read */
-/* shall equal max number of layers read by iisisoff */
-#define FILEREAD_MAX_LAYERS (2)
-
-typedef struct STRUCT_FILEREAD *HANDLE_FILEREAD;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Open an MPEG audio file and try to detect its format.
- * \param filename String of the filename to be opened.
- * \param fileFormat Skip file format detection and use given format if fileFormat != FF_UNKNOWN.
- Else store detected format into *fileFmt.
- * \param transportType Skip transport type detection and use given format if transportType != TT_UNKNOWN.
- Else store detected format into *fileFmt.
- * \param conf Pointer to unsigned char to hold the AudioSpecificConfig of the input file, if
- any (MPEG 4 file format). In case of RAW LATM it holds the StreamMuxConfig.
- * \param confSize Pointer to an integer, where the length of the ASC or SMC (in case of RAW LATM)
- is stored to.
- * \return MPEG file read handle.
- */
-HANDLE_FILEREAD mpegFileRead_Open( const char *filename,
- FILE_FORMAT fileFormat,
- TRANSPORT_TYPE transportType,
- UCHAR *conf[],
- UINT confSize[],
- INT *noOfLayers
- );
-
-/**
- * \brief Get the file format of the input file.
- * \param hDataSrc MPEG file read handle.
- * \return File format of the input file.
- */
-FILE_FORMAT mpegFileRead_GetFileFormat(HANDLE_FILEREAD hDataSrc);
-
-/**
- * \brief Get the transport type of the input file.
- * \param hDataSrc MPEG file read handle.
- * \return Transport type of the input file.
- */
-TRANSPORT_TYPE mpegFileRead_GetTransportType(HANDLE_FILEREAD hDataSrc);
-
-/**
- * \brief Read data from MPEG file. In case of packet file, read one packet, in case
- * of streaming file with embedded synchronisation layer (LOAS/ADTS...), just
- * fill the buffer.
- *
- * \param hMpegFile MPEG file read handle.
- * \param inBuffer Pointer to input buffer.
- * \param bufferSize Size of input buffer.
- * \param bytesValid Number of bytes that were read.
- * \return 0 on success, -1 if unsupported file format or file read error.
- */
-int mpegFileRead_Read( HANDLE_FILEREAD hMpegFile,
- UCHAR *inBuffer[],
- UINT bufferSize,
- UINT *bytesValid
- );
-
-/**
- * \brief Seek in file from origin by given offset in frames.
- * \param hMpegFile MPEG file read handle.
- * \param origin If 0, the origin is the file beginning (absolute seek).
- * If 1, the origin is the current position (relative seek).
- * \param offset The amount of frames to seek from the given origin.
- * \return 0 on sucess, -1 if offset < 0 or file read error.
- */
-int mpegFileRead_seek( HANDLE_FILEREAD hMpegFile,
- INT origin,
- INT offset
- );
-
-/**
- * \brief Get file position in percent.
- * \param hMpegFile MPEG file read handle.
- * \return File position in percent.
- */
-int mpegFileRead_getPercent(HANDLE_FILEREAD hMpegFile);
-
-
-/**
- * \brief Close MPEG audio file.
- * \param hMpegFile Mpeg file read handle.
- * \return 0 on sucess.
- */
-int mpegFileRead_Close(HANDLE_FILEREAD *hMpegFile);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/libMpegTPDec/include/tp_data.h b/libMpegTPDec/include/tp_data.h
index c6e89b5..b4ab802 100644
--- a/libMpegTPDec/include/tp_data.h
+++ b/libMpegTPDec/include/tp_data.h
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,17 +90,18 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
+
+/******************* MPEG transport format decoder library *********************
-/***************************** MPEG-4 AAC Decoder **************************
+ Author(s): Manuel Jander
- Author(s): Manuel Jander
Description: MPEG Transport data tables
-******************************************************************************/
+*******************************************************************************/
-#ifndef __TP_DATA_H__
-#define __TP_DATA_H__
+#ifndef TP_DATA_H
+#define TP_DATA_H
#include "machine_type.h"
#include "FDK_audio.h"
@@ -98,17 +110,35 @@ amm-info@iis.fraunhofer.de
/*
* Configuration
*/
-#define TP_GA_ENABLE
-/* #define TP_CELP_ENABLE */
-/* #define TP_HVXC_ENABLE */
-/* #define TP_SLS_ENABLE */
-#define TP_ELD_ENABLE
-/* #define TP_USAC_ENABLE */
-/* #define TP_RSVD50_ENABLE */
-
-#if defined(TP_GA_ENABLE) || defined(TP_SLS_ENABLE)
-#define TP_PCE_ENABLE /**< Enable full PCE support */
-#endif
+
+#define TP_USAC_MAX_SPEAKERS (24)
+
+#define TP_USAC_MAX_EXT_ELEMENTS ((24))
+
+#define TP_USAC_MAX_ELEMENTS ((24) + TP_USAC_MAX_EXT_ELEMENTS)
+
+#define TP_USAC_MAX_CONFIG_LEN \
+ 512 /* next power of two of maximum of escapedValue(hBs, 4, 4, 8) in \
+ AudioPreRoll() (285) */
+
+#define TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES \
+ (1) /* Number of frames for config change in USAC */
+
+enum {
+ TPDEC_FLUSH_OFF = 0,
+ TPDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON = 1,
+ TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON = 2,
+ TPDEC_USAC_DASH_IPF_FLUSH_ON = 3
+};
+
+enum {
+ TPDEC_BUILD_UP_OFF = 0,
+ TPDEC_RSV60_BUILD_UP_ON = 1,
+ TPDEC_RSV60_BUILD_UP_ON_IN_BAND = 2,
+ TPDEC_USAC_BUILD_UP_ON = 3,
+ TPDEC_RSV60_BUILD_UP_IDLE = 4,
+ TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND = 5
+};
/**
* ProgramConfig struct.
@@ -116,13 +146,12 @@ amm-info@iis.fraunhofer.de
/* ISO/IEC 14496-3 4.4.1.1 Table 4.2 Program config element */
#define PC_FSB_CHANNELS_MAX 16 /* Front/Side/Back channels */
#define PC_LFE_CHANNELS_MAX 4
-#define PC_ASSOCDATA_MAX 8
-#define PC_CCEL_MAX 16 /* CC elements */
-#define PC_COMMENTLENGTH 256
+#define PC_ASSOCDATA_MAX 8
+#define PC_CCEL_MAX 16 /* CC elements */
+#define PC_COMMENTLENGTH 256
+#define PC_NUM_HEIGHT_LAYER 3
-typedef struct
-{
-#ifdef TP_PCE_ENABLE
+typedef struct {
/* PCE bitstream elements: */
UCHAR ElementInstanceTag;
UCHAR Profile;
@@ -165,54 +194,50 @@ typedef struct
UCHAR CommentFieldBytes;
UCHAR Comment[PC_COMMENTLENGTH];
-#endif /* TP_PCE_ENABLE */
/* Helper variables for administration: */
- UCHAR isValid; /*!< Flag showing if PCE has been read successfully. */
- UCHAR NumChannels; /*!< Amount of audio channels summing all channel elements including LFEs */
- UCHAR NumEffectiveChannels; /*!< Amount of audio channels summing only SCEs and CPEs */
+ UCHAR isValid; /*!< Flag showing if PCE has been read successfully. */
+ UCHAR
+ NumChannels; /*!< Amount of audio channels summing all channel elements
+ including LFEs */
+ UCHAR NumEffectiveChannels; /*!< Amount of audio channels summing only SCEs
+ and CPEs */
UCHAR elCounter;
} CProgramConfig;
typedef enum {
ASCEXT_UNKOWN = -1,
- ASCEXT_SBR = 0x2b7,
- ASCEXT_PS = 0x548,
- ASCEXT_MPS = 0x76a,
- ASCEXT_SAOC = 0x7cb,
- ASCEXT_LDMPS = 0x7cc
+ ASCEXT_SBR = 0x2b7,
+ ASCEXT_PS = 0x548,
+ ASCEXT_MPS = 0x76a,
+ ASCEXT_SAOC = 0x7cb,
+ ASCEXT_LDMPS = 0x7cc
} TP_ASC_EXTENSION_ID;
-#ifdef TP_GA_ENABLE
/**
* GaSpecificConfig struct
*/
typedef struct {
- UINT m_frameLengthFlag ;
- UINT m_dependsOnCoreCoder ;
- UINT m_coreCoderDelay ;
+ UINT m_frameLengthFlag;
+ UINT m_dependsOnCoreCoder;
+ UINT m_coreCoderDelay;
- UINT m_extensionFlag ;
- UINT m_extensionFlag3 ;
+ UINT m_extensionFlag;
+ UINT m_extensionFlag3;
UINT m_layer;
UINT m_numOfSubFrame;
UINT m_layerLength;
} CSGaSpecificConfig;
-#endif /* TP_GA_ENABLE */
-
-
-
-
-#ifdef TP_ELD_ENABLE
typedef enum {
- ELDEXT_TERM = 0x0, /* Termination tag */
- ELDEXT_SAOC = 0x1, /* SAOC config */
- ELDEXT_LDSAC = 0x2 /* LD MPEG Surround config */
+ ELDEXT_TERM = 0x0, /* Termination tag */
+ ELDEXT_SAOC = 0x1, /* SAOC config */
+ ELDEXT_LDSAC = 0x2, /* LD MPEG Surround config */
+ ELDEXT_DOWNSCALEINFO = 0x3 /* ELD sample rate adaptation */
/* reserved */
} ASC_ELD_EXT_TYPE;
@@ -220,103 +245,186 @@ typedef struct {
UCHAR m_frameLengthFlag;
UCHAR m_sbrPresentFlag;
- UCHAR m_useLdQmfTimeAlign; /* Use LD-MPS QMF in SBR to achive time alignment */
+ UCHAR
+ m_useLdQmfTimeAlign; /* Use LD-MPS QMF in SBR to achive time alignment */
UCHAR m_sbrSamplingRate;
UCHAR m_sbrCrcFlag;
+ UINT m_downscaledSamplingFrequency;
} CSEldSpecificConfig;
-#endif /* TP_ELD_ENABLE */
+typedef struct {
+ USAC_EXT_ELEMENT_TYPE usacExtElementType;
+ USHORT usacExtElementConfigLength;
+ USHORT usacExtElementDefaultLength;
+ UCHAR usacExtElementPayloadFrag;
+ UCHAR usacExtElementHasAudioPreRoll;
+} CSUsacExtElementConfig;
+typedef struct {
+ MP4_ELEMENT_ID usacElementType;
+ UCHAR m_noiseFilling;
+ UCHAR m_harmonicSBR;
+ UCHAR m_interTes;
+ UCHAR m_pvc;
+ UCHAR m_stereoConfigIndex;
+ CSUsacExtElementConfig extElement;
+} CSUsacElementConfig;
+typedef struct {
+ UCHAR m_frameLengthFlag;
+ UCHAR m_coreSbrFrameLengthIndex;
+ UCHAR m_sbrRatioIndex;
+ UCHAR m_nUsacChannels; /* number of audio channels signaled in
+ UsacDecoderConfig() / rsv603daDecoderConfig() via
+ numElements and usacElementType */
+ UCHAR m_channelConfigurationIndex;
+ UINT m_usacNumElements;
+ CSUsacElementConfig element[TP_USAC_MAX_ELEMENTS];
+
+ UCHAR numAudioChannels;
+ UCHAR m_usacConfigExtensionPresent;
+ UCHAR elementLengthPresent;
+ UCHAR UsacConfig[TP_USAC_MAX_CONFIG_LEN];
+ USHORT UsacConfigBits;
+} CSUsacConfig;
/**
* Audio configuration struct, suitable for encoder and decoder configuration.
*/
typedef struct {
-
/* XYZ Specific Data */
union {
-#ifdef TP_GA_ENABLE
- CSGaSpecificConfig m_gaSpecificConfig; /**< General audio specific configuration. */
-#endif /* TP_GA_ENABLE */
-#ifdef TP_ELD_ENABLE
- CSEldSpecificConfig m_eldSpecificConfig; /**< ELD specific configuration. */
-#endif /* TP_ELD_ENABLE */
+ CSGaSpecificConfig
+ m_gaSpecificConfig; /**< General audio specific configuration. */
+ CSEldSpecificConfig m_eldSpecificConfig; /**< ELD specific configuration. */
+ CSUsacConfig m_usacConfig; /**< USAC specific configuration */
} m_sc;
-
- /* Common ASC parameters */
-#ifdef TP_PCE_ENABLE
- CProgramConfig m_progrConfigElement; /**< Program configuration. */
-#endif /* TP_PCE_ENABLE */
-
- AUDIO_OBJECT_TYPE m_aot; /**< Audio Object Type. */
- UINT m_samplingFrequency; /**< Samplerate. */
- UINT m_samplesPerFrame; /**< Amount of samples per frame. */
- UINT m_directMapping; /**< Document this please !! */
-
- AUDIO_OBJECT_TYPE m_extensionAudioObjectType; /**< Audio object type */
- UINT m_extensionSamplingFrequency; /**< Samplerate */
- SCHAR m_channelConfiguration; /**< Channel configuration index */
-
- SCHAR m_epConfig; /**< Error protection index */
- SCHAR m_vcb11Flag; /**< aacSectionDataResilienceFlag */
- SCHAR m_rvlcFlag; /**< aacScalefactorDataResilienceFlag */
- SCHAR m_hcrFlag; /**< aacSpectralDataResilienceFlag */
-
- SCHAR m_sbrPresentFlag; /**< Flag indicating the presence of SBR data in the bitstream */
- SCHAR m_psPresentFlag; /**< Flag indicating the presence of parametric stereo data in the bitstream */
- UCHAR m_samplingFrequencyIndex; /**< Samplerate index */
- UCHAR m_extensionSamplingFrequencyIndex; /**< Samplerate index */
- SCHAR m_extensionChannelConfiguration; /**< Channel configuration index */
+ /* Common ASC parameters */
+ CProgramConfig m_progrConfigElement; /**< Program configuration. */
+
+ AUDIO_OBJECT_TYPE m_aot; /**< Audio Object Type. */
+ UINT m_samplingFrequency; /**< Samplerate. */
+ UINT m_samplesPerFrame; /**< Amount of samples per frame. */
+ UINT m_directMapping; /**< Document this please !! */
+
+ AUDIO_OBJECT_TYPE m_extensionAudioObjectType; /**< Audio object type */
+ UINT m_extensionSamplingFrequency; /**< Samplerate */
+
+ SCHAR m_channelConfiguration; /**< Channel configuration index */
+
+ SCHAR m_epConfig; /**< Error protection index */
+ SCHAR m_vcb11Flag; /**< aacSectionDataResilienceFlag */
+ SCHAR m_rvlcFlag; /**< aacScalefactorDataResilienceFlag */
+ SCHAR m_hcrFlag; /**< aacSpectralDataResilienceFlag */
+
+ SCHAR m_sbrPresentFlag; /**< Flag indicating the presence of SBR data in the
+ bitstream */
+ SCHAR
+ m_psPresentFlag; /**< Flag indicating the presence of parametric stereo
+ data in the bitstream */
+ UCHAR m_samplingFrequencyIndex; /**< Samplerate index */
+ UCHAR m_extensionSamplingFrequencyIndex; /**< Samplerate index */
+ SCHAR m_extensionChannelConfiguration; /**< Channel configuration index */
+
+ UCHAR
+ configMode; /**< The flag indicates if the callback shall work in memory
+ allocation mode or in config change detection mode */
+ UCHAR AacConfigChanged; /**< The flag will be set if at least one aac config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+ UCHAR SbrConfigChanged; /**< The flag will be set if at least one sbr config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+ UCHAR SacConfigChanged; /**< The flag will be set if at least one sac config
+ parameter has changed that requires a memory
+ reconfiguration, otherwise it will be cleared */
+
+ UCHAR
+ config[TP_USAC_MAX_CONFIG_LEN]; /**< Configuration stored as bitstream */
+ UINT configBits; /**< Configuration length in bits */
} CSAudioSpecificConfig;
-typedef INT (*cbUpdateConfig_t)(void*, const CSAudioSpecificConfig*);
-typedef INT (*cbSsc_t)(
- void*, HANDLE_FDK_BITSTREAM,
- const AUDIO_OBJECT_TYPE coreCodec,
- const INT samplingFrequency,
- const INT muxMode,
- const INT configBytes
- );
-typedef INT (*cbSbr_t)(
- void * self,
- HANDLE_FDK_BITSTREAM hBs,
- const INT sampleRateIn,
- const INT sampleRateOut,
- const INT samplesPerFrame,
- const AUDIO_OBJECT_TYPE coreCodec,
- const MP4_ELEMENT_ID elementID,
- const INT elementIndex
- );
-
-typedef struct {
- cbUpdateConfig_t cbUpdateConfig; /*!< Function pointer for Config change notify callback. */
- void *cbUpdateConfigData; /*!< User data pointer for Config change notify callback. */
- cbSsc_t cbSsc; /*!< Function pointer for SSC parser callback. */
- void *cbSscData; /*!< User data pointer for SSC parser callback. */
- cbSbr_t cbSbr; /*!< Function pointer for SBR header parser callback. */
- void *cbSbrData; /*!< User data pointer for SBR header parser callback. */
+typedef struct {
+ SCHAR flushCnt; /**< Flush frame counter */
+ UCHAR flushStatus; /**< Flag indicates flush mode: on|off */
+ SCHAR buildUpCnt; /**< Build up frame counter */
+ UCHAR buildUpStatus; /**< Flag indicates build up mode: on|off */
+ UCHAR cfgChanged; /**< Flag indicates that the config changed and the decoder
+ needs to be initialized again via callback. Make sure
+ that memory is freed before initialization. */
+ UCHAR contentChanged; /**< Flag indicates that the content changed i.e. a
+ right truncation occured before */
+ UCHAR forceCfgChange; /**< Flag indicates if config change has to be forced
+ even if new config is the same */
+} CCtrlCFGChange;
+
+typedef INT (*cbUpdateConfig_t)(void *, const CSAudioSpecificConfig *,
+ const UCHAR configMode, UCHAR *configChanged);
+typedef INT (*cbFreeMem_t)(void *, const CSAudioSpecificConfig *);
+typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *);
+typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const INT samplingRate, const INT stereoConfigIndex,
+ const INT coreSbrFrameLengthIndex, const INT configBytes,
+ const UCHAR configMode, UCHAR *configChanged);
+
+typedef INT (*cbSbr_t)(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const INT sampleRateIn, const INT sampleRateOut,
+ const INT samplesPerFrame,
+ const AUDIO_OBJECT_TYPE coreCodec,
+ const MP4_ELEMENT_ID elementID, const INT elementIndex,
+ const UCHAR harmonicSbr, const UCHAR stereoConfigIndex,
+ const UCHAR configMode, UCHAR *configChanged,
+ const INT downscaleFactor);
+
+typedef INT (*cbUsac_t)(void *self, HANDLE_FDK_BITSTREAM hBs);
+
+typedef INT (*cbUniDrc_t)(void *self, HANDLE_FDK_BITSTREAM hBs,
+ const INT fullPayloadLength, const INT payloadType,
+ const INT subStreamIndex, const INT payloadStart,
+ const AUDIO_OBJECT_TYPE);
+
+typedef struct {
+ cbUpdateConfig_t cbUpdateConfig; /*!< Function pointer for Config change
+ notify callback. */
+ void *cbUpdateConfigData; /*!< User data pointer for Config change notify
+ callback. */
+ cbFreeMem_t cbFreeMem; /*!< Function pointer for free memory callback. */
+ void *cbFreeMemData; /*!< User data pointer for free memory callback. */
+ cbCtrlCFGChange_t cbCtrlCFGChange; /*!< Function pointer for config change
+ control callback. */
+ void *cbCtrlCFGChangeData; /*!< User data pointer for config change control
+ callback. */
+ cbSsc_t cbSsc; /*!< Function pointer for SSC parser callback. */
+ void *cbSscData; /*!< User data pointer for SSC parser callback. */
+ cbSbr_t cbSbr; /*!< Function pointer for SBR header parser callback. */
+ void *cbSbrData; /*!< User data pointer for SBR header parser callback. */
+ cbUsac_t cbUsac;
+ void *cbUsacData;
+ cbUniDrc_t cbUniDrc; /*!< Function pointer for uniDrcConfig and
+ loudnessInfoSet parser callback. */
+ void *cbUniDrcData; /*!< User data pointer for uniDrcConfig and
+ loudnessInfoSet parser callback. */
} CSTpCallBacks;
-static const UINT SamplingRateTable[] =
-{ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0,
- 0
-};
+static const UINT SamplingRateTable[] = {
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025,
+ 8000, 7350, 0, 0, 57600, 51200, 40000, 38400, 34150, 28800, 25600,
+ 20000, 19200, 17075, 14400, 12800, 9600, 0, 0, 0, 0};
-static inline
-int getSamplingRateIndex( UINT samplingRate )
-{
- UINT sf_index, tableSize=sizeof(SamplingRateTable)/sizeof(UINT);
+static inline int getSamplingRateIndex(UINT samplingRate, UINT nBits) {
+ UINT sf_index;
+ UINT tableSize = (1 << nBits) - 1;
- for (sf_index=0; sf_index<tableSize; sf_index++) {
- if( SamplingRateTable[sf_index] == samplingRate ) break;
+ for (sf_index = 0; sf_index < tableSize; sf_index++) {
+ if (SamplingRateTable[sf_index] == samplingRate) break;
}
- if (sf_index>tableSize-1) {
- return tableSize-1;
+ if (sf_index > tableSize) {
+ return tableSize - 1;
}
return sf_index;
@@ -325,26 +433,33 @@ int getSamplingRateIndex( UINT samplingRate )
/*
* Get Channel count from channel configuration
*/
-static inline int getNumberOfTotalChannels(int channelConfig)
-{
+static inline int getNumberOfTotalChannels(int channelConfig) {
switch (channelConfig) {
- case 1: case 2: case 3:
- case 4: case 5: case 6:
- return channelConfig;
- case 7: case 12: case 14:
- return 8;
- case 11:
- return 7;
- default:
- return 0;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ return channelConfig;
+ case 7:
+ case 12:
+ case 14:
+ return 8;
+ case 11:
+ return 7;
+ case 13:
+ return 24;
+ default:
+ return 0;
}
}
-static inline
-int getNumberOfEffectiveChannels(const int channelConfig)
-{ /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */
- const int n[] = {0,1,2,3,4,5,5,7,0,0, 0, 6, 7, 0, 7, 0};
+static inline int getNumberOfEffectiveChannels(
+ const int
+ channelConfig) { /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */
+ const int n[] = {0, 1, 2, 3, 4, 5, 5, 7, 0, 0, 0, 6, 7, 22, 7, 0};
return n[channelConfig];
}
-#endif /* __TP_DATA_H__ */
+#endif /* TP_DATA_H */
diff --git a/libMpegTPDec/include/tpdec_lib.h b/libMpegTPDec/include/tpdec_lib.h
index 2ad397d..30e53c1 100644
--- a/libMpegTPDec/include/tpdec_lib.h
+++ b/libMpegTPDec/include/tpdec_lib.h
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,114 +90,115 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
+
+/******************* MPEG transport format decoder library *********************
-/************************** MPEG-4 Transport Decoder ***********************
+ Author(s): Manuel Jander
- Author(s): Manuel Jander
Description: MPEG Transport decoder
-******************************************************************************/
+*******************************************************************************/
-#ifndef __TPDEC_LIB_H__
-#define __TPDEC_LIB_H__
+#ifndef TPDEC_LIB_H
+#define TPDEC_LIB_H
#include "tp_data.h"
#include "FDK_bitstream.h"
-#define TRANSPORTDEC_INBUF_SIZE ( 8192 ) /*!< Size is in bytes.
- Set the transport input buffer size carefully and
- assure that it fulfills the requirements of the
- supported transport format(s). */
-
typedef enum {
- TRANSPORTDEC_OK = 0, /*!< All fine. */
+ TRANSPORTDEC_OK = 0, /*!< All fine. */
/* Synchronization errors. Wait for new input data and try again. */
- tpdec_sync_error_start = 0x100,
- TRANSPORTDEC_NOT_ENOUGH_BITS, /*!< Out of bits. Provide more bits and try again. */
- TRANSPORTDEC_SYNC_ERROR, /*!< No sync was found or sync got lost. Keep trying. */
+ tpdec_sync_error_start = 0x100,
+ TRANSPORTDEC_NOT_ENOUGH_BITS, /*!< Out of bits. Provide more bits and try
+ again. */
+ TRANSPORTDEC_SYNC_ERROR, /*!< No sync was found or sync got lost. Keep trying.
+ */
tpdec_sync_error_end,
/* Decode errors. Mostly caused due to bit errors. */
tpdec_decode_error_start = 0x400,
- TRANSPORTDEC_PARSE_ERROR, /*!< Bitstream data showed inconsistencies (wrong syntax). */
- TRANSPORTDEC_UNSUPPORTED_FORMAT, /*!< Unsupported format or feature found in the bitstream data. */
- TRANSPORTDEC_CRC_ERROR, /*!< CRC error encountered in bitstream data. */
+ TRANSPORTDEC_PARSE_ERROR, /*!< Bitstream data showed inconsistencies (wrong
+ syntax). */
+ TRANSPORTDEC_UNSUPPORTED_FORMAT, /*!< Unsupported format or feature found in
+ the bitstream data. */
+ TRANSPORTDEC_CRC_ERROR, /*!< CRC error encountered in bitstream data. */
tpdec_decode_error_end,
/* Fatal errors. Stop immediately on one of these errors! */
- tpdec_fatal_error_start = 0x200,
- TRANSPORTDEC_UNKOWN_ERROR, /*!< An unknown error occured. */
- TRANSPORTDEC_INVALID_PARAMETER, /*!< An invalid parameter was passed to a function. */
- TRANSPORTDEC_NEED_TO_RESTART, /*!< The decoder needs to be restarted, since the requiered
- configuration change cannot be performed. */
+ tpdec_fatal_error_start = 0x200,
+ TRANSPORTDEC_UNKOWN_ERROR, /*!< An unknown error occured. */
+ TRANSPORTDEC_INVALID_PARAMETER, /*!< An invalid parameter was passed to a
+ function. */
+ TRANSPORTDEC_NEED_TO_RESTART, /*!< The decoder needs to be restarted, since
+ the requiered configuration change cannot
+ be performed. */
+ TRANSPORTDEC_TOO_MANY_BITS, /*!< In case of packet based formats: Supplied
+ number of bits exceed the size of the
+ internal bit buffer. */
tpdec_fatal_error_end
} TRANSPORTDEC_ERROR;
-
/** Macro to identify decode errors. */
-#define TPDEC_IS_DECODE_ERROR(err) ( ((err>=tpdec_decode_error_start) && (err<=tpdec_decode_error_end)) ? 1 : 0)
+#define TPDEC_IS_DECODE_ERROR(err) \
+ (((err >= tpdec_decode_error_start) && (err <= tpdec_decode_error_end)) ? 1 \
+ : 0)
/** Macro to identify fatal errors. */
-#define TPDEC_IS_FATAL_ERROR(err) ( ((err>=tpdec_fatal_error_start) && (err<=tpdec_fatal_error_end)) ? 1 : 0)
-
+#define TPDEC_IS_FATAL_ERROR(err) \
+ (((err >= tpdec_fatal_error_start) && (err <= tpdec_fatal_error_end)) ? 1 : 0)
/**
* \brief Parameter identifiers for transportDec_SetParam()
*/
typedef enum {
- TPDEC_PARAM_MINIMIZE_DELAY = 1, /** Delay minimization strategy. 0: none, 1: discard as many frames as possible. */
- TPDEC_PARAM_EARLY_CONFIG, /** Enable early config discovery. */
- TPDEC_PARAM_IGNORE_BUFFERFULLNESS, /** Ignore buffer fullness. */
- TPDEC_PARAM_SET_BITRATE, /** Set average bit rate for bit stream interruption frame misses estimation. */
- TPDEC_PARAM_RESET, /** Reset transport decoder instance status. */
- TPDEC_PARAM_BURST_PERIOD /** Set data reception burst period in mili seconds. */
+ TPDEC_PARAM_MINIMIZE_DELAY = 1, /** Delay minimization strategy. 0: none, 1:
+ discard as many frames as possible. */
+ TPDEC_PARAM_EARLY_CONFIG, /** Enable early config discovery. */
+ TPDEC_PARAM_IGNORE_BUFFERFULLNESS, /** Ignore buffer fullness. */
+ TPDEC_PARAM_SET_BITRATE, /** Set average bit rate for bit stream interruption
+ frame misses estimation. */
+ TPDEC_PARAM_RESET, /** Reset transport decoder instance status. */
+ TPDEC_PARAM_BURST_PERIOD, /** Set data reception burst period in mili seconds.
+ */
+ TPDEC_PARAM_TARGETLAYOUT, /** Set CICP target layout */
+ TPDEC_PARAM_FORCE_CONFIG_CHANGE, /** Force config change for next received
+ config */
+ TPDEC_PARAM_USE_ELEM_SKIPPING
} TPDEC_PARAM;
-/* ISO/IEC 14496-3 4.4.1.1 Table 4.2 Program config element */
-#define PC_FSB_CHANNELS_MAX 16 /* Front/Side/Back channels */
-#define PC_LFE_CHANNELS_MAX 4
-#define PC_ASSOCDATA_MAX 8
-#define PC_CCEL_MAX 16 /* CC elements */
-#define PC_COMMENTLENGTH 256
-#define PC_NUM_HEIGHT_LAYER 3
-
-
/*!
\brief Reset Program Config Element.
\param pPce Program Config Element structure.
\return void
*/
-void CProgramConfig_Reset ( CProgramConfig *pPce );
+void CProgramConfig_Reset(CProgramConfig *pPce);
/*!
\brief Initialize Program Config Element.
\param pPce Program Config Element structure.
\return void
*/
-void CProgramConfig_Init ( CProgramConfig *pPce );
+void CProgramConfig_Init(CProgramConfig *pPce);
/*!
- \brief Inquire state of present Program Config Element structure.
- \param pPce Program Config Element structure.
- \return 1 if the PCE structure is filled correct,
- 0 if no valid PCE present.
+ \brief Inquire state of present Program Config Element
+ structure. \param pPce Program Config Element structure. \return
+ 1 if the PCE structure is filled correct, 0 if no valid PCE present.
*/
-int CProgramConfig_IsValid ( const CProgramConfig *pPce );
+int CProgramConfig_IsValid(const CProgramConfig *pPce);
-#ifdef TP_PCE_ENABLE
/*!
\brief Read Program Config Element.
\param pPce Program Config Element structure.
\param bs Bitstream buffer to read from.
- \param alignAnchor Align bitstream to alignAnchor bits after all read operations.
- \return void
+ \param alignAnchor Align bitstream to alignAnchor bits after all read
+ operations. \return void
*/
-void CProgramConfig_Read ( CProgramConfig *pPce,
- HANDLE_FDK_BITSTREAM bs,
- UINT alignAnchor );
+void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
+ UINT alignAnchor);
/*!
\brief Compare two Program Config Elements.
@@ -194,50 +206,57 @@ void CProgramConfig_Read ( CProgramConfig *pPce,
\param pPce2 Pointer to second Program Config Element structure.
\return -1 if PCEs are completely different,
0 if PCEs are completely equal,
- 1 if PCEs are different but have the same channel config,
- 2 if PCEs have different channel config but same number of channels.
+ 1 if PCEs are different but have the same channel
+ config, 2 if PCEs have different channel config but same number of channels.
*/
-int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
- const CProgramConfig * const pPce2 );
+int CProgramConfig_Compare(const CProgramConfig *const pPce1,
+ const CProgramConfig *const pPce2);
/*!
- \brief Get a Program Config Element that matches the predefined MPEG-4 channel configurations 1-14.
- \param pPce Program Config Element structure.
- \param channelConfig MPEG-4 channel configuration.
- \return void
+ \brief Get a Program Config Element that matches the predefined
+ MPEG-4 channel configurations 1-14. \param pPce Program Config
+ Element structure. \param channelConfig MPEG-4 channel configuration. \return
+ void
*/
-void CProgramConfig_GetDefault ( CProgramConfig *pPce,
- const UINT channelConfig );
-#endif /* TP_PCE_ENABLE */
+void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig);
/**
* \brief Lookup and verify a given element. The decoder calls this
* method with every new element ID found in the bitstream.
*
* \param pPce A valid Program config structure.
+ * \param chConfig MPEG-4 channel configuration.
* \param tag Tag of the current element to be looked up.
* \param channelIdx The current channel count of the decoder parser.
* \param chMapping Array to store the canonical channel mapping indexes.
* \param chType Array to store the audio channel type.
* \param chIndex Array to store the individual audio channel type index.
+ * \param chDescrLen Length of the output channel description array.
* \param elMapping Pointer where the canonical element index is stored.
* \param elType The element id of the current element to be looked up.
*
- * \return Non-zero if the element belongs to the current program, zero
- * if it does not.
- */
-int CProgramConfig_LookupElement(
- CProgramConfig *pPce,
- UINT channelConfig,
- const UINT tag,
- const UINT channelIdx,
- UCHAR chMapping[],
- AUDIO_CHANNEL_TYPE chType[],
- UCHAR chIndex[],
- UCHAR *elMapping,
- MP4_ELEMENT_ID elList[],
- MP4_ELEMENT_ID elType
- );
+ * \return Non-zero if the element belongs to the current program,
+ * zero if it does not.
+ */
+int CProgramConfig_LookupElement(CProgramConfig *pPce, UINT chConfig,
+ const UINT tag, const UINT channelIdx,
+ UCHAR chMapping[], AUDIO_CHANNEL_TYPE chType[],
+ UCHAR chIndex[], const UINT chDescrLen,
+ UCHAR *elMapping, MP4_ELEMENT_ID elList[],
+ MP4_ELEMENT_ID elType);
+
+/**
+ * \brief Get table of channel indices in the order of their
+ * appearance in by the program config field.
+ * \param pPce A valid program config structure.
+ * \param pceChMap Array to store the channel mapping indices like they
+ * appear in the PCE.
+ * \param pceChMapLen Lenght of the channel mapping index array (pceChMap).
+ *
+ * \return Non-zero if any error occured otherwise zero.
+ */
+int CProgramConfig_GetPceChMap(const CProgramConfig *pPce, UCHAR pceChMap[],
+ const UINT pceChMapLen);
/**
* \brief Get table of elements in canonical order from a
@@ -250,10 +269,22 @@ int CProgramConfig_LookupElement(
* PCE. If none can be found it receives the value 0.
* \return Total element count including all SCE, CPE and LFE.
*/
-int CProgramConfig_GetElementTable( const CProgramConfig *pPce,
- MP4_ELEMENT_ID table[],
- const INT elListSize,
- UCHAR *pChMapIdx );
+int CProgramConfig_GetElementTable(const CProgramConfig *pPce,
+ MP4_ELEMENT_ID table[], const INT elListSize,
+ UCHAR *pChMapIdx);
+
+/**
+ * \brief Get channel description (type and index) for implicit
+ configurations (chConfig > 0) in MPEG canonical order.
+ * \param chConfig MPEG-4 channel configuration.
+ * \param chType Array to store the audio channel type.
+ * \param chIndex Array to store the individual audio channel type index.
+ * \return void
+ */
+void CProgramConfig_GetChannelDescription(const UINT chConfig,
+ const CProgramConfig *pPce,
+ AUDIO_CHANNEL_TYPE chType[],
+ UCHAR chIndex[]);
/**
* \brief Initialize a given AudioSpecificConfig structure.
@@ -265,45 +296,50 @@ void AudioSpecificConfig_Init(CSAudioSpecificConfig *pAsc);
/**
* \brief Parse a AudioSpecificConfig from a given bitstream handle.
*
- * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct.
+ * \param pAsc A pointer to an allocated
+ * CSAudioSpecificConfig struct.
* \param hBs Bitstream handle.
- * \param fExplicitBackwardCompatible Do explicit backward compatibility parsing if set (flag).
+ * \param fExplicitBackwardCompatible Do explicit backward compatibility
+ * parsing if set (flag).
* \param cb pointer to structure holding callback information
+ * \param configMode Config modes: memory allocation mode or config change
+ * detection mode.
+ * \param configChanged Indicates a config change.
+ * \param m_aot in case of unequal AOT_NULL_OBJECT only the specific config is
+ * parsed.
*
* \return Total element count including all SCE, CPE and LFE.
*/
TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
- CSAudioSpecificConfig *pAsc,
- HANDLE_FDK_BITSTREAM hBs,
- int fExplicitBackwardCompatible,
- CSTpCallBacks *cb
- );
+ CSAudioSpecificConfig *pAsc, HANDLE_FDK_BITSTREAM hBs,
+ int fExplicitBackwardCompatible, CSTpCallBacks *cb, UCHAR configMode,
+ UCHAR configChanged, AUDIO_OBJECT_TYPE m_aot);
/* CELP stuff */
-enum {
- MPE = 0,
- RPE = 1,
- fs8KHz = 0,
- fs16KHz = 1
-};
+enum { MPE = 0, RPE = 1, fs8KHz = 0, fs16KHz = 1 };
/* Defintion of flags that can be passed to transportDecOpen() */
#define TP_FLAG_MPEG4 1
/* Capability flags */
-#define CAPF_TPDEC_ADIF 0x00001000 /**< Flag indicating support for ADIF transport format. */
-#define CAPF_TPDEC_ADTS 0x00002000 /**< Flag indicating support for ADTS transport format. */
-#define CAPF_TPDEC_LOAS 0x00004000 /**< Flag indicating support for LOAS transport format. */
-#define CAPF_TPDEC_LATM 0x00008000 /**< Flag indicating support for LATM transport format. */
-#define CAPF_TPDEC_RAWPACKETS 0x00010000 /**< Flag indicating support for raw packets transport format. */
+#define CAPF_TPDEC_ADIF \
+ 0x00001000 /**< Flag indicating support for ADIF transport format. */
+#define CAPF_TPDEC_ADTS \
+ 0x00002000 /**< Flag indicating support for ADTS transport format. */
+#define CAPF_TPDEC_LOAS \
+ 0x00004000 /**< Flag indicating support for LOAS transport format. */
+#define CAPF_TPDEC_LATM \
+ 0x00008000 /**< Flag indicating support for LATM transport format. */
+#define CAPF_TPDEC_RAWPACKETS \
+ 0x00010000 /**< Flag indicating support for raw packets transport format. */
typedef struct TRANSPORTDEC *HANDLE_TRANSPORTDEC;
-
/**
- * \brief Configure Transport Decoder via a binary coded AudioSpecificConfig or StreamMuxConfig.
- * The previously requested configuration callback will be called as well. The buffer conf
- * must containt a SMC in case of LOAS/LATM transport format, and an ASC elseways.
+ * \brief Configure Transport Decoder via a binary coded AudioSpecificConfig or
+ * StreamMuxConfig. The previously requested configuration callback will be
+ * called as well. The buffer conf must containt a SMC in case of
+ * LOAS/LATM transport format, and an ASC elseways.
*
* \param hTp Handle of a transport decoder.
* \param conf UCHAR buffer of the binary coded config (ASC or SMC).
@@ -311,96 +347,174 @@ typedef struct TRANSPORTDEC *HANDLE_TRANSPORTDEC;
*
* \return Error code.
*/
-TRANSPORTDEC_ERROR transportDec_OutOfBandConfig( const HANDLE_TRANSPORTDEC hTp,
- UCHAR *conf,
- const UINT length,
- const UINT layer );
+TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(const HANDLE_TRANSPORTDEC hTp,
+ UCHAR *conf, const UINT length,
+ const UINT layer);
+
+/**
+ * \brief Configure Transport Decoder via a binary coded USAC/RSV603DA Config.
+ * The buffer newConfig contains a binary coded USAC/RSV603DA config of
+ * length newConfigLength bytes. If the new config and the previous config are
+ * different configChanged is set to 1 otherwise it is set to 0.
+ *
+ * \param hTp Handle of a transport decoder.
+ * \param newConfig buffer of the binary coded config.
+ * \param newConfigLength Length of new config in bytes.
+ * \param buildUpStatus Indicates build up status: off|on|idle.
+ * \param configChanged Indicates if config changed.
+ * \param layer Instance layer.
+ *
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_InBandConfig(
+ const HANDLE_TRANSPORTDEC hTp, UCHAR *newConfig, const UINT newConfigLength,
+ const UCHAR buildUpStatus, UCHAR *configChanged, const UINT layer,
+ UCHAR *implicitExplicitCfgDiff);
/**
* \brief Open Transport medium for reading.
*
* \param transportDecFmt Format of the transport decoder medium to be accessed.
- * \param flags Transport decoder flags. Currently only TP_FLAG_MPEG4, which signals a
- * MPEG4 capable decoder (relevant for ADTS only).
+ * \param flags Transport decoder flags. Currently only TP_FLAG_MPEG4,
+ * which signals a MPEG4 capable decoder (relevant for ADTS only).
*
- * \return A pointer to a valid and allocated HANDLE_TRANSPORTDEC or a null pointer on failure.
+ * \return A pointer to a valid and allocated HANDLE_TRANSPORTDEC or a null
+ * pointer on failure.
*/
-HANDLE_TRANSPORTDEC transportDec_Open( TRANSPORT_TYPE transportDecFmt,
- const UINT flags );
+HANDLE_TRANSPORTDEC transportDec_Open(TRANSPORT_TYPE transportDecFmt,
+ const UINT flags, const UINT nrOfLayer);
/**
* \brief Register configuration change callback.
* \param hTp Handle of transport decoder.
- * \param cbUpdateConfig Pointer to a callback function to handle audio config changes.
- * \param user_data void pointer for user data passed to the callback as first parameter.
+ * \param cbUpdateConfig Pointer to a callback function to handle audio config
+ * changes.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
* \return 0 on success.
*/
-int transportDec_RegisterAscCallback (
- HANDLE_TRANSPORTDEC hTp,
- const cbUpdateConfig_t cbUpdateConfig,
- void* user_data );
+int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTp,
+ const cbUpdateConfig_t cbUpdateConfig,
+ void *user_data);
+
+/**
+ * \brief Register free memory callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbFreeMem Pointer to a callback function to free config dependent
+ * memory.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTp,
+ const cbFreeMem_t cbFreeMem,
+ void *user_data);
+
+/**
+ * \brief Register config change control callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbCtrlCFGChange Pointer to a callback function for config change
+ * control.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterCtrlCFGChangeCallback(
+ HANDLE_TRANSPORTDEC hTp, const cbCtrlCFGChange_t cbCtrlCFGChange,
+ void *user_data);
/**
* \brief Register SSC parser callback.
* \param hTp Handle of transport decoder.
* \param cbUpdateConfig Pointer to a callback function to handle SSC parsing.
- * \param user_data void pointer for user data passed to the callback as first parameter.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
* \return 0 on success.
*/
-int transportDec_RegisterSscCallback (
- HANDLE_TRANSPORTDEC hTp,
- const cbSsc_t cbSscParse,
- void* user_data );
+int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTp,
+ const cbSsc_t cbSscParse, void *user_data);
/**
* \brief Register SBR header parser callback.
* \param hTp Handle of transport decoder.
- * \param cbUpdateConfig Pointer to a callback function to handle SBR header parsing.
- * \param user_data void pointer for user data passed to the callback as first parameter.
- * \return 0 on success.
+ * \param cbUpdateConfig Pointer to a callback function to handle SBR header
+ * parsing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbSbr_t cbSbr, void *user_data);
+
+/**
+ * \brief Register USAC SC parser callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle USAC SC
+ * parsing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
+ */
+int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUsac_t cbUsac, void *user_data);
+
+/**
+ * \brief Register uniDrcConfig and loudnessInfoSet parser
+ * callback.
+ * \param hTp Handle of transport decoder.
+ * \param cbUpdateConfig Pointer to a callback function to handle uniDrcConfig
+ * and loudnessInfoSet parsing.
+ * \param user_data void pointer for user data passed to the callback as
+ * first parameter.
+ * \return 0 on success.
*/
-int transportDec_RegisterSbrCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSbr_t cbSbr, void* user_data);
+int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUniDrc_t cbUniDrc,
+ void *user_data,
+ UINT *pLoudnessInfoSetPosition);
/**
- * \brief Fill internal input buffer with bitstream data from the external input buffer.
- * The function only copies such data as long as the decoder-internal input buffer is not full.
- * So it grabs whatever it can from pBuffer and returns information (bytesValid) so that at a
- * subsequent call of %transportDec_FillData(), the right position in pBuffer can be determined to
+ * \brief Fill internal input buffer with bitstream data from the external input
+ * buffer. The function only copies such data as long as the decoder-internal
+ * input buffer is not full. So it grabs whatever it can from pBuffer and
+ * returns information (bytesValid) so that at a subsequent call of
+ * %transportDec_FillData(), the right position in pBuffer can be determined to
* grab the next data.
*
* \param hTp Handle of transportDec.
* \param pBuffer Pointer to external input buffer.
- * \param bufferSize Size of external input buffer. This argument is required because decoder-internally
- * we need the information to calculate the offset to pBuffer, where the next
- * available data is, which is then fed into the decoder-internal buffer (as much
- * as possible). Our example framework implementation fills the buffer at pBuffer
- * again, once it contains no available valid bytes anymore (meaning bytesValid equal 0).
- * \param bytesValid Number of bitstream bytes in the external bitstream buffer that have not yet been
- * copied into the decoder's internal bitstream buffer by calling this function.
- * The value is updated according to the amount of newly copied bytes.
+ * \param bufferSize Size of external input buffer. This argument is required
+ * because decoder-internally we need the information to calculate the offset to
+ * pBuffer, where the next available data is, which is then
+ * fed into the decoder-internal buffer (as much as
+ * possible). Our example framework implementation fills the
+ * buffer at pBuffer again, once it contains no available valid bytes anymore
+ * (meaning bytesValid equal 0).
+ * \param bytesValid Number of bitstream bytes in the external bitstream buffer
+ * that have not yet been copied into the decoder's internal bitstream buffer by
+ * calling this function. The value is updated according to
+ * the amount of newly copied bytes.
* \param layer The layer the bitstream belongs to.
* \return Error code.
*/
-TRANSPORTDEC_ERROR transportDec_FillData(
- const HANDLE_TRANSPORTDEC hTp,
- UCHAR *pBuffer,
- const UINT bufferSize,
- UINT *pBytesValid,
- const INT layer );
+TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
+ UCHAR *pBuffer, const UINT bufferSize,
+ UINT *pBytesValid, const INT layer);
/**
* \brief Get transportDec bitstream handle.
* \param hTp Pointer to a transport decoder handle.
* \return HANDLE_FDK_BITSTREAM bitstream handle.
*/
-HANDLE_FDK_BITSTREAM transportDec_GetBitstream ( const HANDLE_TRANSPORTDEC hTp, const UINT layer );
+HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer);
/**
* \brief Get transport format.
* \param hTp Pointer to a transport decoder handle.
* \return The transport format.
*/
-TRANSPORT_TYPE transportDec_GetFormat ( const HANDLE_TRANSPORTDEC hTp );
+TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp);
/**
* \brief Get the current buffer fullness value.
@@ -409,60 +523,76 @@ TRANSPORT_TYPE transportDec_GetFormat ( const HANDLE_TRANSPORTDEC hTp );
*
* \return Buffer fullness
*/
-INT transportDec_GetBufferFullness( const HANDLE_TRANSPORTDEC hTp );
+INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp);
/**
* \brief Close and deallocate transportDec.
* \param phTp Pointer to a previously allocated transport decoder handle.
* \return void
*/
-void transportDec_Close ( HANDLE_TRANSPORTDEC *phTp );
+void transportDec_Close(HANDLE_TRANSPORTDEC *phTp);
/**
* \brief Read one access unit from the transportDec medium.
* \param hTp Handle of transportDec.
- * \param length On return, this value is overwritten with the actual access unit length in bits.
- * Set to -1 if length is unknown.
+ * \param length On return, this value is overwritten with the actual access
+ * unit length in bits. Set to -1 if length is unknown.
* \return Error code.
*/
-TRANSPORTDEC_ERROR transportDec_ReadAccessUnit ( const HANDLE_TRANSPORTDEC hTp, const UINT layer );
+TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer);
/**
- * \brief Get the remaining amount of bits of the current access unit. The result
- * can be below zero, meaning that too many bits have been read.
+ * \brief Get AudioSpecificConfig.
+ * \param hTp Handle of transportDec.
+ * \param layer Transport layer.
+ * \param asc Pointer to AudioSpecificConfig.
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer,
+ CSAudioSpecificConfig *asc);
+
+/**
+ * \brief Get the remaining amount of bits of the current access unit. The
+ * result can be below zero, meaning that too many bits have been read.
* \param hTp Handle of transportDec.
* \return amount of remaining bits.
*/
-INT transportDec_GetAuBitsRemaining( const HANDLE_TRANSPORTDEC hTp, const UINT layer );
+INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer);
/**
* \brief Get the total amount of bits of the current access unit.
* \param hTp Handle of transportDec.
* \return amount of total bits.
*/
-INT transportDec_GetAuBitsTotal( const HANDLE_TRANSPORTDEC hTp, const UINT layer );
+INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer);
/**
- * \brief This function is required to be called when the decoder has finished parsing
- * one Access Unit for bitstream housekeeping.
+ * \brief This function is required to be called when the decoder has
+ * finished parsing one Access Unit for bitstream housekeeping.
* \param hTp Transport Handle.
* \return Error code.
*/
-TRANSPORTDEC_ERROR transportDec_EndAccessUnit ( const HANDLE_TRANSPORTDEC hTp );
+TRANSPORTDEC_ERROR transportDec_EndAccessUnit(const HANDLE_TRANSPORTDEC hTp);
/**
- * \brief Obtain the amount of missing access units if applicable in case of
- * a bit stream synchronization error. Each time transportDec_ReadAccessUnit()
- * returns TRANSPORTDEC_SYNC_ERROR this function can be called to retrieve an estimate
- * of the amount of missing access units. This works only in case of constant average
- * bit rate (has to be known) and if the parameter TPDEC_PARAM_SET_BITRATE has been set
- * accordingly.
+ * \brief Obtain the amount of missing access units if applicable in case
+ * of a bit stream synchronization error. Each time
+ * transportDec_ReadAccessUnit() returns TRANSPORTDEC_SYNC_ERROR
+ * this function can be called to retrieve an estimate of the amount
+ * of missing access units. This works only in case of constant
+ * average bit rate (has to be known) and if the parameter
+ * TPDEC_PARAM_SET_BITRATE has been set accordingly.
* \param hTp Transport Handle.
- * \param pNAccessUnits pointer to a memory location where the estimated lost frame count will be stored into.
+ * \param pNAccessUnits pointer to a memory location where the estimated lost
+ * frame count will be stored into.
* \return Error code.
*/
-TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount ( INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp );
-
+TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
+ INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp);
/**
* \brief Set a given setting.
@@ -471,35 +601,36 @@ TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount ( INT *pNAccessUnits,
* \param value Value for the parameter to be changed.
* \return Error code.
*/
-TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp,
- const TPDEC_PARAM param,
- const INT value );
+TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
+ const TPDEC_PARAM param,
+ const INT value);
/**
* \brief Get number of subframes (for LATM or ADTS)
* \param hTp Transport Handle.
- * \return Number of ADTS/LATM subframes (return 1 for all other transport types).
+ * \return Number of ADTS/LATM subframes (return 1 for all other transport
+ * types).
*/
UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp);
-
/**
* \brief Get info structure of transport decoder library.
* \param info A pointer to an allocated LIB_INFO struct.
* \return Error code.
*/
-TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info );
+TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info);
/* ADTS CRC support */
/**
* \brief Set current bitstream position as start of a new data region.
* \param hTp Transport handle.
- * \param mBits Size in bits of the data region. Set to 0 if it should not be of a fixed size.
- * \return Data region ID, which should be used when calling transportDec_CrcEndReg().
+ * \param mBits Size in bits of the data region. Set to 0 if it should not be
+ * of a fixed size.
+ * \return Data region ID, which should be used when calling
+ * transportDec_CrcEndReg().
*/
-int transportDec_CrcStartReg ( const HANDLE_TRANSPORTDEC hTp,
- const INT mBits );
+int transportDec_CrcStartReg(const HANDLE_TRANSPORTDEC hTp, const INT mBits);
/**
* \brief Set end of data region.
@@ -507,15 +638,27 @@ int transportDec_CrcStartReg ( const HANDLE_TRANSPORTDEC hTp,
* \param reg Data region ID, opbtained from transportDec_CrcStartReg().
* \return void
*/
-void transportDec_CrcEndReg ( const HANDLE_TRANSPORTDEC hTp,
- const INT reg );
+void transportDec_CrcEndReg(const HANDLE_TRANSPORTDEC hTp, const INT reg);
/**
- * \brief Calculate ADTS crc and check if it is correct. The ADTS checksum is held internally.
+ * \brief Calculate ADTS crc and check if it is correct. The ADTS checksum
+ * is held internally.
* \param hTp Transport handle.
- * \return Return TRANSPORTDEC_OK if the CRC is ok, or error if CRC is not correct.
+ * \return Return TRANSPORTDEC_OK if the CRC is ok, or error if CRC is not
+ * correct.
*/
-TRANSPORTDEC_ERROR transportDec_CrcCheck ( const HANDLE_TRANSPORTDEC hTp );
+TRANSPORTDEC_ERROR transportDec_CrcCheck(const HANDLE_TRANSPORTDEC hTp);
+/**
+ * \brief Only check whether a given config seems to be valid without modifying
+ * internal states.
+ *
+ * \param conf UCHAR buffer of the binary coded config (SDC type 9).
+ * \param length The length in bytes of the conf buffer.
+ *
+ * \return Error code.
+ */
+TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
+ const UINT length);
-#endif /* #ifndef __TPDEC_LIB_H__ */
+#endif /* #ifndef TPDEC_LIB_H */
diff --git a/libMpegTPDec/src/mpegFileFormat.h b/libMpegTPDec/src/mpegFileFormat.h
deleted file mode 100644
index b0cfe9e..0000000
--- a/libMpegTPDec/src/mpegFileFormat.h
+++ /dev/null
@@ -1,114 +0,0 @@
-
-/* -----------------------------------------------------------------------------------------------------------
-Software License for The Fraunhofer FDK AAC Codec Library for Android
-
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
-
- 1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
-
-2. COPYRIGHT LICENSE
-
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
-
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
-
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
-modifications thereto to recipients of copies in binary form.
-
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
-
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
-
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
-
-3. NO PATENT LICENSE
-
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
-
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
-
-4. DISCLAIMER
-
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
-
-5. CONTACT INFORMATION
-
-Fraunhofer Institute for Integrated Circuits IIS
-Attention: Audio and Multimedia Departments - FDK AAC LL
-Am Wolfsmantel 33
-91058 Erlangen, Germany
-
-www.iis.fraunhofer.de/amm
-amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
-
-/*************************** Fraunhofer IIS FDK Tools ***********************
-
- Author(s): Oliver Moser
- Description: bitstream format detection routines
-
-******************************************************************************/
-
-#if !defined(__BITSTREAM_FORMAT_H__)
-#define __BITSTREAM_FORMAT_H__
-
-#include "machine_type.h"
-#include "FDK_audio.h"
-
-/**
- * \brief Try to find out the format of a file, given the few first bytes.
- * \param fileData pointer to a buffer holding the first bytes of a file.
- * \param pAu pointer to UCHAR*, returns the address of the first AU found or NULL.
- * \param length pointer to the length of the buffer fileData. Return length of first AU.
- * \return the detected file format, or FF_UNKNOWN in case of failure.
- */
-FILE_FORMAT GetFileFormat(UCHAR *fileData, UCHAR **pAu, UINT *length);
-
-/**
- * \brief Try to find out the transport type contained in a given file.
- * \param filename name of the file to be analysed.
- * \param fileFormat pointer to a variable where the detected file format is stored into.
- * \return the detected transport type or TT_UNKNOWN in case of failure.
- */
-TRANSPORT_TYPE GetTransportType(const char* filename, FILE_FORMAT *fileFormat);
-
-#endif
diff --git a/libMpegTPDec/src/tp_version.h b/libMpegTPDec/src/tp_version.h
new file mode 100644
index 0000000..4faed8c
--- /dev/null
+++ b/libMpegTPDec/src/tp_version.h
@@ -0,0 +1,118 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/******************* MPEG transport format decoder library *********************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+#if !defined(TP_VERSION_H)
+#define TP_VERSION_H
+
+/* library info */
+#define TP_LIB_VL0 3
+#define TP_LIB_VL1 0
+#define TP_LIB_VL2 0
+#define TP_LIB_TITLE "MPEG Transport"
+#ifdef __ANDROID__
+#define TP_LIB_BUILD_DATE ""
+#define TP_LIB_BUILD_TIME ""
+#else
+#define TP_LIB_BUILD_DATE __DATE__
+#define TP_LIB_BUILD_TIME __TIME__
+#endif
+#endif /* !defined(TP_VERSION_H) */
diff --git a/libMpegTPDec/src/tpdec_adif.cpp b/libMpegTPDec/src/tpdec_adif.cpp
index 237e881..ec20b9b 100644
--- a/libMpegTPDec/src/tpdec_adif.cpp
+++ b/libMpegTPDec/src/tpdec_adif.cpp
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,27 +90,24 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Josef Hoepfl
+
Description: ADIF reader
-******************************************************************************/
+*******************************************************************************/
#include "tpdec_adif.h"
-
#include "FDK_bitstream.h"
#include "genericStds.h"
-TRANSPORTDEC_ERROR adifRead_DecodeHeader(
- CAdifHeader *pAdifHeader,
- CProgramConfig *pPce,
- HANDLE_FDK_BITSTREAM bs
- )
-{
+TRANSPORTDEC_ERROR adifRead_DecodeHeader(CAdifHeader *pAdifHeader,
+ CProgramConfig *pPce,
+ HANDLE_FDK_BITSTREAM bs) {
int i;
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
UINT startAnchor = FDKgetValidBits(bs);
@@ -108,41 +116,39 @@ TRANSPORTDEC_ERROR adifRead_DecodeHeader(
return (TRANSPORTDEC_NOT_ENOUGH_BITS);
}
- if (FDKreadBits(bs,8) != 'A') {
+ if (FDKreadBits(bs, 8) != 'A') {
return (TRANSPORTDEC_SYNC_ERROR);
}
- if (FDKreadBits(bs,8) != 'D') {
+ if (FDKreadBits(bs, 8) != 'D') {
return (TRANSPORTDEC_SYNC_ERROR);
}
- if (FDKreadBits(bs,8) != 'I') {
+ if (FDKreadBits(bs, 8) != 'I') {
return (TRANSPORTDEC_SYNC_ERROR);
}
- if (FDKreadBits(bs,8) != 'F') {
+ if (FDKreadBits(bs, 8) != 'F') {
return (TRANSPORTDEC_SYNC_ERROR);
}
- if ( (pAdifHeader->CopyrightIdPresent = FDKreadBits(bs,1)) != 0 )
- FDKpushBiDirectional(bs,72); /* CopyrightId */
-
+ if ((pAdifHeader->CopyrightIdPresent = FDKreadBits(bs, 1)) != 0)
+ FDKpushBiDirectional(bs, 72); /* CopyrightId */
- pAdifHeader->OriginalCopy = FDKreadBits(bs,1);
- pAdifHeader->Home = FDKreadBits(bs,1);
- pAdifHeader->BitstreamType = FDKreadBits(bs,1);
+ pAdifHeader->OriginalCopy = FDKreadBits(bs, 1);
+ pAdifHeader->Home = FDKreadBits(bs, 1);
+ pAdifHeader->BitstreamType = FDKreadBits(bs, 1);
/* pAdifHeader->BitRate = FDKreadBits(bs, 23); */
- pAdifHeader->BitRate = FDKreadBits(bs,16);
+ pAdifHeader->BitRate = FDKreadBits(bs, 16);
pAdifHeader->BitRate <<= 7;
- pAdifHeader->BitRate |= FDKreadBits(bs,7);
+ pAdifHeader->BitRate |= FDKreadBits(bs, 7);
- pAdifHeader->NumProgramConfigElements = FDKreadBits(bs,4) + 1;
+ pAdifHeader->NumProgramConfigElements = FDKreadBits(bs, 4) + 1;
if (pAdifHeader->BitstreamType == 0) {
- FDKpushBiDirectional(bs,20); /* adif_buffer_fullness */
+ FDKpushBiDirectional(bs, 20); /* adif_buffer_fullness */
}
/* Parse all PCEs but keep only one */
- for (i=0; i < pAdifHeader->NumProgramConfigElements; i++)
- {
+ for (i = 0; i < pAdifHeader->NumProgramConfigElements; i++) {
CProgramConfig_Read(pPce, bs, startAnchor);
}
@@ -150,6 +156,3 @@ TRANSPORTDEC_ERROR adifRead_DecodeHeader(
return (ErrorStatus);
}
-
-
-
diff --git a/libMpegTPDec/src/tpdec_adif.h b/libMpegTPDec/src/tpdec_adif.h
index d6780a7..72ccc6a 100644
--- a/libMpegTPDec/src/tpdec_adif.h
+++ b/libMpegTPDec/src/tpdec_adif.h
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,24 +90,24 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Josef Hoepfl
+
Description: ADIF reader
-******************************************************************************/
+*******************************************************************************/
#ifndef TPDEC_ADIF_H
#define TPDEC_ADIF_H
#include "tpdec_lib.h"
-#define MIN_ADIF_HEADERLENGTH 63 /* in bits */
+#define MIN_ADIF_HEADERLENGTH 63 /* in bits */
-typedef struct
-{
+typedef struct {
INT NumProgramConfigElements;
UINT BitRate;
UCHAR CopyrightIdPresent;
@@ -106,18 +117,18 @@ typedef struct
} CAdifHeader;
/**
- * \brief Parse a ADIF header at the given bitstream and store the parsed data into a given CAdifHeader
- * and CProgramConfig struct
+ * \brief Parse a ADIF header at the given bitstream and store the parsed data
+ * into a given CAdifHeader and CProgramConfig struct
*
- * \param pAdifHeader pointer to a CAdifHeader structure to hold the parsed ADIF header data.
- * \param pPce pointer to a CProgramConfig structure where the last PCE will remain.
+ * \param pAdifHeader pointer to a CAdifHeader structure to hold the parsed ADIF
+ * header data.
+ * \param pPce pointer to a CProgramConfig structure where the last PCE will
+ * remain.
*
* \return TRANSPORTDEC_ERROR error code
*/
-TRANSPORTDEC_ERROR adifRead_DecodeHeader(
- CAdifHeader *pAdifHeader,
- CProgramConfig *pPce,
- HANDLE_FDK_BITSTREAM bs
- );
+TRANSPORTDEC_ERROR adifRead_DecodeHeader(CAdifHeader *pAdifHeader,
+ CProgramConfig *pPce,
+ HANDLE_FDK_BITSTREAM bs);
#endif /* TPDEC_ADIF_H */
diff --git a/libMpegTPDec/src/tpdec_adts.cpp b/libMpegTPDec/src/tpdec_adts.cpp
index c455681..6dc0275 100644
--- a/libMpegTPDec/src/tpdec_adts.cpp
+++ b/libMpegTPDec/src/tpdec_adts.cpp
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,96 +90,83 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Josef Hoepfl
+
Description: ADTS interface
-******************************************************************************/
+*******************************************************************************/
#include "tpdec_adts.h"
-
#include "FDK_bitstream.h"
-
-
-void adtsRead_CrcInit(HANDLE_ADTS pAdts) /*!< pointer to adts crc info stucture */
+void adtsRead_CrcInit(
+ HANDLE_ADTS pAdts) /*!< pointer to adts crc info stucture */
{
FDKcrcInit(&pAdts->crcInfo, 0x8005, 0xFFFF, 16);
}
int adtsRead_CrcStartReg(
- HANDLE_ADTS pAdts, /*!< pointer to adts stucture */
- HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
- int mBits /*!< number of bits in crc region */
- )
-{
+ HANDLE_ADTS pAdts, /*!< pointer to adts stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+) {
if (pAdts->bs.protection_absent) {
return 0;
}
- return ( FDKcrcStartReg(&pAdts->crcInfo, hBs, mBits) );
-
+ return (FDKcrcStartReg(&pAdts->crcInfo, hBs, mBits));
}
void adtsRead_CrcEndReg(
- HANDLE_ADTS pAdts, /*!< pointer to adts crc info stucture */
- HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
- int reg /*!< crc region */
- )
-{
- if (pAdts->bs.protection_absent == 0)
- {
+ HANDLE_ADTS pAdts, /*!< pointer to adts crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+) {
+ if (pAdts->bs.protection_absent == 0) {
FDKcrcEndReg(&pAdts->crcInfo, hBs, reg);
}
}
-TRANSPORTDEC_ERROR adtsRead_CrcCheck( HANDLE_ADTS pAdts )
-{
+TRANSPORTDEC_ERROR adtsRead_CrcCheck(HANDLE_ADTS pAdts) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
USHORT crc;
- if (pAdts->bs.protection_absent)
- return TRANSPORTDEC_OK;
+ if (pAdts->bs.protection_absent) return TRANSPORTDEC_OK;
crc = FDKcrcGetCRC(&pAdts->crcInfo);
- if (crc != pAdts->crcReadValue)
- {
+ if (crc != pAdts->crcReadValue) {
return (TRANSPORTDEC_CRC_ERROR);
}
return (ErrorStatus);
}
-
-
-#define Adts_Length_SyncWord 12
-#define Adts_Length_Id 1
-#define Adts_Length_Layer 2
-#define Adts_Length_ProtectionAbsent 1
-#define Adts_Length_Profile 2
-#define Adts_Length_SamplingFrequencyIndex 4
-#define Adts_Length_PrivateBit 1
-#define Adts_Length_ChannelConfiguration 3
-#define Adts_Length_OriginalCopy 1
-#define Adts_Length_Home 1
-#define Adts_Length_CopyrightIdentificationBit 1
-#define Adts_Length_CopyrightIdentificationStart 1
-#define Adts_Length_FrameLength 13
-#define Adts_Length_BufferFullness 11
-#define Adts_Length_NumberOfRawDataBlocksInFrame 2
-#define Adts_Length_CrcCheck 16
-
-TRANSPORTDEC_ERROR adtsRead_DecodeHeader(
- HANDLE_ADTS pAdts,
- CSAudioSpecificConfig *pAsc,
- HANDLE_FDK_BITSTREAM hBs,
- const INT ignoreBufferFullness
- )
-{
+#define Adts_Length_SyncWord 12
+#define Adts_Length_Id 1
+#define Adts_Length_Layer 2
+#define Adts_Length_ProtectionAbsent 1
+#define Adts_Length_Profile 2
+#define Adts_Length_SamplingFrequencyIndex 4
+#define Adts_Length_PrivateBit 1
+#define Adts_Length_ChannelConfiguration 3
+#define Adts_Length_OriginalCopy 1
+#define Adts_Length_Home 1
+#define Adts_Length_CopyrightIdentificationBit 1
+#define Adts_Length_CopyrightIdentificationStart 1
+#define Adts_Length_FrameLength 13
+#define Adts_Length_BufferFullness 11
+#define Adts_Length_NumberOfRawDataBlocksInFrame 2
+#define Adts_Length_CrcCheck 16
+
+TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
+ CSAudioSpecificConfig *pAsc,
+ HANDLE_FDK_BITSTREAM hBs,
+ const INT ignoreBufferFullness) {
INT crcReg;
INT valBits;
@@ -177,58 +175,58 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(
STRUCT_ADTS_BS bs;
-#ifdef TP_PCE_ENABLE
CProgramConfig oldPce;
/* Store the old PCE temporarily. Maybe we'll need it later if we
have channelConfig=0 and no PCE in this frame. */
FDKmemcpy(&oldPce, &pAsc->m_progrConfigElement, sizeof(CProgramConfig));
-#endif
valBits = FDKgetValidBits(hBs);
/* adts_fixed_header */
- bs.mpeg_id = FDKreadBits(hBs, Adts_Length_Id);
- bs.layer = FDKreadBits(hBs, Adts_Length_Layer);
+ bs.mpeg_id = FDKreadBits(hBs, Adts_Length_Id);
+ bs.layer = FDKreadBits(hBs, Adts_Length_Layer);
bs.protection_absent = FDKreadBits(hBs, Adts_Length_ProtectionAbsent);
- bs.profile = FDKreadBits(hBs, Adts_Length_Profile);
+ bs.profile = FDKreadBits(hBs, Adts_Length_Profile);
bs.sample_freq_index = FDKreadBits(hBs, Adts_Length_SamplingFrequencyIndex);
- bs.private_bit = FDKreadBits(hBs, Adts_Length_PrivateBit);
- bs.channel_config = FDKreadBits(hBs, Adts_Length_ChannelConfiguration);
- bs.original = FDKreadBits(hBs, Adts_Length_OriginalCopy);
- bs.home = FDKreadBits(hBs, Adts_Length_Home);
+ bs.private_bit = FDKreadBits(hBs, Adts_Length_PrivateBit);
+ bs.channel_config = FDKreadBits(hBs, Adts_Length_ChannelConfiguration);
+ bs.original = FDKreadBits(hBs, Adts_Length_OriginalCopy);
+ bs.home = FDKreadBits(hBs, Adts_Length_Home);
/* adts_variable_header */
- bs.copyright_id = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationBit);
- bs.copyright_start = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationStart);
- bs.frame_length = FDKreadBits(hBs, Adts_Length_FrameLength);
- bs.adts_fullness = FDKreadBits(hBs, Adts_Length_BufferFullness);
- bs.num_raw_blocks = FDKreadBits(hBs, Adts_Length_NumberOfRawDataBlocksInFrame);
- bs.num_pce_bits = 0;
+ bs.copyright_id = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationBit);
+ bs.copyright_start =
+ FDKreadBits(hBs, Adts_Length_CopyrightIdentificationStart);
+ bs.frame_length = FDKreadBits(hBs, Adts_Length_FrameLength);
+ bs.adts_fullness = FDKreadBits(hBs, Adts_Length_BufferFullness);
+ bs.num_raw_blocks =
+ FDKreadBits(hBs, Adts_Length_NumberOfRawDataBlocksInFrame);
+ bs.num_pce_bits = 0;
adtsHeaderLength = ADTS_HEADERLENGTH;
if (!bs.protection_absent) {
FDKcrcReset(&pAdts->crcInfo);
- FDKpushBack(hBs, 56); /* complete fixed and variable header! */
+ FDKpushBack(hBs, 56); /* complete fixed and variable header! */
crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0);
FDKpushFor(hBs, 56);
}
- if (! bs.protection_absent && bs.num_raw_blocks>0) {
- for (i=0; i<bs.num_raw_blocks; i++) {
+ if (!bs.protection_absent && bs.num_raw_blocks > 0) {
+ for (i = 0; i < bs.num_raw_blocks; i++) {
pAdts->rawDataBlockDist[i] = (USHORT)FDKreadBits(hBs, 16);
adtsHeaderLength += 16;
}
/* Change raw data blocks to delta values */
- pAdts->rawDataBlockDist[bs.num_raw_blocks] = bs.frame_length - 7 - bs.num_raw_blocks*2 - 2 ;
- for (i=bs.num_raw_blocks; i>0; i--) {
- pAdts->rawDataBlockDist[i] -= pAdts->rawDataBlockDist[i-1];
+ pAdts->rawDataBlockDist[bs.num_raw_blocks] =
+ bs.frame_length - 7 - bs.num_raw_blocks * 2 - 2;
+ for (i = bs.num_raw_blocks; i > 0; i--) {
+ pAdts->rawDataBlockDist[i] -= pAdts->rawDataBlockDist[i - 1];
}
}
/* adts_error_check */
- if (!bs.protection_absent)
- {
+ if (!bs.protection_absent) {
USHORT crc_check;
FDKcrcEndReg(&pAdts->crcInfo, hBs, crcReg);
@@ -246,75 +244,63 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(
}
}
-
/* check if valid header */
- if (
- (bs.layer != 0) || // we only support MPEG ADTS
- (bs.sample_freq_index >= 13) // we only support 96kHz - 7350kHz
- ) {
- FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later
+ if ((bs.layer != 0) || // we only support MPEG ADTS
+ (bs.sample_freq_index >= 13) // we only support 96kHz - 7350kHz
+ ) {
+ FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
/* special treatment of id-bit */
- if ( (bs.mpeg_id == 0) && (pAdts->decoderCanDoMpeg4 == 0) )
- {
+ if ((bs.mpeg_id == 0) && (pAdts->decoderCanDoMpeg4 == 0)) {
/* MPEG-2 decoder cannot play MPEG-4 bitstreams */
-
FDKpushFor(hBs, bs.frame_length * 8); // try again one frame later
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
- if (!ignoreBufferFullness)
- {
- cmp_buffer_fullness = bs.frame_length*8 + bs.adts_fullness*32*getNumberOfEffectiveChannels(bs.channel_config);
-
+ if (!ignoreBufferFullness) {
+ cmp_buffer_fullness =
+ bs.frame_length * 8 +
+ bs.adts_fullness * 32 * getNumberOfEffectiveChannels(bs.channel_config);
/* Evaluate buffer fullness */
- if (bs.adts_fullness != 0x7FF)
- {
- if (pAdts->BufferFullnesStartFlag)
- {
- if ( valBits < cmp_buffer_fullness )
- {
+ if (bs.adts_fullness != 0x7FF) {
+ if (pAdts->BufferFullnesStartFlag) {
+ if (valBits < cmp_buffer_fullness) {
/* Condition for start of decoding is not fulfilled */
/* The current frame will not be decoded */
FDKpushBack(hBs, adtsHeaderLength);
- if ( (cmp_buffer_fullness+adtsHeaderLength) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
+ if ((cmp_buffer_fullness + adtsHeaderLength) >
+ (((8192 * 4) << 3) - 7)) {
return TRANSPORTDEC_SYNC_ERROR;
} else {
return TRANSPORTDEC_NOT_ENOUGH_BITS;
}
- }
- else
- {
+ } else {
pAdts->BufferFullnesStartFlag = 0;
}
}
}
}
-
/* Get info from ADTS header */
AudioSpecificConfig_Init(pAsc);
- pAsc->m_aot = (AUDIO_OBJECT_TYPE)(bs.profile + 1);
+ pAsc->m_aot = (AUDIO_OBJECT_TYPE)(bs.profile + 1);
pAsc->m_samplingFrequencyIndex = bs.sample_freq_index;
- pAsc->m_samplingFrequency = SamplingRateTable[bs.sample_freq_index];
- pAsc->m_channelConfiguration = bs.channel_config;
- pAsc->m_samplesPerFrame = 1024;
+ pAsc->m_samplingFrequency = SamplingRateTable[bs.sample_freq_index];
+ pAsc->m_channelConfiguration = bs.channel_config;
+ pAsc->m_samplesPerFrame = 1024;
-#ifdef TP_PCE_ENABLE
- if (bs.channel_config == 0)
- {
+ if (bs.channel_config == 0) {
int pceBits = 0;
UINT alignAnchor = FDKgetValidBits(hBs);
-
- if (FDKreadBits(hBs,3) == ID_PCE) {
+
+ if (FDKreadBits(hBs, 3) == ID_PCE) {
/* Got luck! Parse the PCE */
- int crcReg;
crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0);
CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor);
@@ -323,25 +309,26 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(
pceBits = alignAnchor - FDKgetValidBits(hBs);
/* store the number of PCE bits */
bs.num_pce_bits = pceBits;
- }
- else {
+ } else {
/* No PCE in this frame! Push back the ID tag bits. */
- FDKpushBack(hBs,3);
+ FDKpushBack(hBs, 3);
/* Encoders do not have to write a PCE in each frame.
So if we already have a valid PCE we have to use it. */
- if ( oldPce.isValid
- && (bs.sample_freq_index == pAdts->bs.sample_freq_index) /* we could compare the complete fixed header (bytes) here! */
- && (bs.channel_config == pAdts->bs.channel_config) /* == 0 */
- && (bs.mpeg_id == pAdts->bs.mpeg_id) )
- { /* Restore previous PCE which is still valid */
+ if (oldPce.isValid &&
+ (bs.sample_freq_index ==
+ pAdts->bs.sample_freq_index) /* we could compare the complete fixed
+ header (bytes) here! */
+ && (bs.channel_config == pAdts->bs.channel_config) /* == 0 */
+ &&
+ (bs.mpeg_id ==
+ pAdts->bs.mpeg_id)) { /* Restore previous PCE which is still valid */
FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, sizeof(CProgramConfig));
- }
- else if (bs.mpeg_id == 0) {
+ } else if (bs.mpeg_id == 0) {
/* If not it seems that we have a implicit channel configuration.
This mode is not allowed in the context of ISO/IEC 14496-3.
Skip this frame and try the next one. */
- FDKpushFor(hBs, (bs.frame_length<<3) - adtsHeaderLength - 3);
+ FDKpushFor(hBs, (bs.frame_length << 3) - adtsHeaderLength - 3);
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
/* else {
@@ -350,33 +337,32 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(
} */
}
}
-#endif /* TP_PCE_ENABLE */
- /* Copy bit stream data struct to persistent memory now, once we passed all sanity checks above. */
+ /* Copy bit stream data struct to persistent memory now, once we passed all
+ * sanity checks above. */
FDKmemcpy(&pAdts->bs, &bs, sizeof(STRUCT_ADTS_BS));
return TRANSPORTDEC_OK;
}
-int adtsRead_GetRawDataBlockLength(
- HANDLE_ADTS pAdts,
- INT blockNum
- )
-{
+int adtsRead_GetRawDataBlockLength(HANDLE_ADTS pAdts, INT blockNum) {
int length;
if (pAdts->bs.num_raw_blocks == 0) {
- length = (pAdts->bs.frame_length - 7) << 3; /* aac_frame_length subtracted by the header size (7 bytes). */
+ length =
+ (pAdts->bs.frame_length - 7)
+ << 3; /* aac_frame_length subtracted by the header size (7 bytes). */
if (pAdts->bs.protection_absent == 0)
- length -= 16; /* substract 16 bit CRC */
+ length -= 16; /* substract 16 bit CRC */
} else {
if (pAdts->bs.protection_absent) {
length = -1; /* raw data block length is unknown */
} else {
if (blockNum < 0 || blockNum > 3) {
length = -1;
+ } else {
+ length = (pAdts->rawDataBlockDist[blockNum] << 3) - 16;
}
- length = (pAdts->rawDataBlockDist[blockNum] << 3) - 16;
}
}
if (blockNum == 0 && length > 0) {
@@ -384,5 +370,3 @@ int adtsRead_GetRawDataBlockLength(
}
return length;
}
-
-
diff --git a/libMpegTPDec/src/tpdec_adts.h b/libMpegTPDec/src/tpdec_adts.h
index a3b83a5..68f3f63 100644
--- a/libMpegTPDec/src/tpdec_adts.h
+++ b/libMpegTPDec/src/tpdec_adts.h
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,31 +90,31 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Josef Hoepfl
+
Description: ADTS interface
-******************************************************************************/
+*******************************************************************************/
#ifndef TPDEC_ADTS_H
#define TPDEC_ADTS_H
#include "tpdec_lib.h"
-
-#define ADTS_SYNCWORD ( 0xfff )
-#define ADTS_SYNCLENGTH ( 12 ) /* in bits */
-#define ADTS_HEADERLENGTH ( 56 ) /* minimum header size in bits */
-#define ADTS_FIXED_HEADERLENGTH ( 28 ) /* in bits */
-#define ADTS_VARIABLE_HEADERLENGTH ( ADTS_HEADERLENGTH - ADTS_FIXED_HEADERLENGTH )
+#define ADTS_SYNCWORD (0xfff)
+#define ADTS_SYNCLENGTH (12) /* in bits */
+#define ADTS_HEADERLENGTH (56) /* minimum header size in bits */
+#define ADTS_FIXED_HEADERLENGTH (28) /* in bits */
+#define ADTS_VARIABLE_HEADERLENGTH (ADTS_HEADERLENGTH - ADTS_FIXED_HEADERLENGTH)
#ifdef CHECK_TWO_SYNCS
- #define ADTS_MIN_TP_BUF_SIZE ( 8191 + 2 )
+#define ADTS_MIN_TP_BUF_SIZE (8191 + 2)
#else
- #define ADTS_MIN_TP_BUF_SIZE ( 8191 )
+#define ADTS_MIN_TP_BUF_SIZE (8191)
#endif
#include "FDK_crc.h"
@@ -128,16 +139,16 @@ typedef struct {
} STRUCT_ADTS_BS;
struct STRUCT_ADTS {
-
STRUCT_ADTS_BS bs;
UCHAR decoderCanDoMpeg4;
UCHAR BufferFullnesStartFlag;
- FDK_CRCINFO crcInfo; /* CRC state info */
- USHORT crcReadValue; /* CRC value read from bitstream data */
- USHORT rawDataBlockDist[4]; /* distance between each raw data block. Not the same as found in the bitstream */
-} ;
+ FDK_CRCINFO crcInfo; /* CRC state info */
+ USHORT crcReadValue; /* CRC value read from bitstream data */
+ USHORT rawDataBlockDist[4]; /* distance between each raw data block. Not the
+ same as found in the bitstream */
+};
typedef struct STRUCT_ADTS *HANDLE_ADTS;
@@ -148,15 +159,14 @@ typedef struct STRUCT_ADTS *HANDLE_ADTS;
\return none
*/
-void adtsRead_CrcInit( HANDLE_ADTS pAdts );
+void adtsRead_CrcInit(HANDLE_ADTS pAdts);
/**
* \brief Starts CRC region with a maximum number of bits
- * If mBits is positive zero padding will be used for CRC calculation, if there
- * are less than mBits bits available.
- * If mBits is negative no zero padding is done.
- * If mBits is zero the memory for the buffer is allocated dynamically, the
- * number of bits is not limited.
+ * If mBits is positive zero padding will be used for CRC calculation, if
+ * there are less than mBits bits available. If mBits is negative no zero
+ * padding is done. If mBits is zero the memory for the buffer is
+ * allocated dynamically, the number of bits is not limited.
*
* \param pAdts ADTS data handle
* \param hBs bitstream handle, on which the CRC region referes to
@@ -164,11 +174,8 @@ void adtsRead_CrcInit( HANDLE_ADTS pAdts );
*
* \return ID for the created region, -1 in case of an error
*/
-int adtsRead_CrcStartReg(
- HANDLE_ADTS pAdts,
- HANDLE_FDK_BITSTREAM hBs,
- int mBits
- );
+int adtsRead_CrcStartReg(HANDLE_ADTS pAdts, HANDLE_FDK_BITSTREAM hBs,
+ int mBits);
/**
* \brief Ends CRC region identified by reg
@@ -179,58 +186,49 @@ int adtsRead_CrcStartReg(
*
* \return none
*/
-void adtsRead_CrcEndReg(
- HANDLE_ADTS pAdts,
- HANDLE_FDK_BITSTREAM hBs,
- int reg
- );
+void adtsRead_CrcEndReg(HANDLE_ADTS pAdts, HANDLE_FDK_BITSTREAM hBs, int reg);
/**
* \brief Check CRC
*
- * Checks if the currently calculated CRC matches the CRC field read from the bitstream
- * Deletes all CRC regions.
+ * Checks if the currently calculated CRC matches the CRC field read from the
+ * bitstream Deletes all CRC regions.
*
* \param pAdts ADTS data handle
*
* \return Returns 0 if they are identical otherwise 1
*/
-TRANSPORTDEC_ERROR adtsRead_CrcCheck( HANDLE_ADTS pAdts );
-
+TRANSPORTDEC_ERROR adtsRead_CrcCheck(HANDLE_ADTS pAdts);
/**
* \brief Check if we have a valid ADTS frame at the current bitbuffer position
*
* This function assumes enough bits in buffer for the current frame.
* It reads out the header bits to prepare the bitbuffer for the decode loop.
- * In case the header bits show an invalid bitstream/frame, the whole frame is skipped.
+ * In case the header bits show an invalid bitstream/frame, the whole frame is
+ * skipped.
*
* \param pAdts ADTS data handle which is filled with parsed ADTS header data
* \param bs handle of bitstream from whom the ADTS header is read
*
* \return error status
*/
-TRANSPORTDEC_ERROR adtsRead_DecodeHeader(
- HANDLE_ADTS pAdts,
- CSAudioSpecificConfig *pAsc,
- HANDLE_FDK_BITSTREAM bs,
- const INT ignoreBufferFullness
- );
+TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts,
+ CSAudioSpecificConfig *pAsc,
+ HANDLE_FDK_BITSTREAM bs,
+ const INT ignoreBufferFullness);
/**
* \brief Get the raw data block length of the given block number.
*
* \param pAdts ADTS data handle
* \param blockNum current raw data block index
- * \param pLength pointer to an INT where the length of the given raw data block is stored into
- * the returned value might be -1, in which case the raw data block length is unknown.
+ * \param pLength pointer to an INT where the length of the given raw data block
+ * is stored into the returned value might be -1, in which case the raw data
+ * block length is unknown.
*
* \return error status
*/
-int adtsRead_GetRawDataBlockLength(
- HANDLE_ADTS pAdts,
- INT blockNum
- );
-
+int adtsRead_GetRawDataBlockLength(HANDLE_ADTS pAdts, INT blockNum);
#endif /* TPDEC_ADTS_H */
diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp
index e80d0e5..abe66e5 100644
--- a/libMpegTPDec/src/tpdec_asc.cpp
+++ b/libMpegTPDec/src/tpdec_asc.cpp
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,42 +90,109 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Daniel Homm
+
Description:
-******************************************************************************/
+*******************************************************************************/
#include "tpdec_lib.h"
#include "tp_data.h"
-#ifdef TP_PCE_ENABLE
-#include "FDK_crc.h"
-#endif
+#include "FDK_crc.h"
-void CProgramConfig_Reset(CProgramConfig *pPce)
-{
- pPce->elCounter = 0;
-}
+#include "common_fix.h"
-void CProgramConfig_Init(CProgramConfig *pPce)
-{
+/**
+ * The following arrays provide the IDs of the consecutive elements for each
+ * channel configuration. Every channel_configuration has to be finalized with
+ * ID_NONE.
+ */
+static const MP4_ELEMENT_ID channel_configuration_0[] = {ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_1[] = {ID_SCE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_2[] = {ID_CPE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_3[] = {ID_SCE, ID_CPE,
+ ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_4[] = {ID_SCE, ID_CPE, ID_SCE,
+ ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_5[] = {ID_SCE, ID_CPE, ID_CPE,
+ ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_6[] = {ID_SCE, ID_CPE, ID_CPE,
+ ID_LFE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_7[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_8[] = {
+ ID_NONE}; /* reserved */
+static const MP4_ELEMENT_ID channel_configuration_9[] = {
+ ID_NONE}; /* reserved */
+static const MP4_ELEMENT_ID channel_configuration_10[] = {
+ ID_NONE}; /* reserved */
+static const MP4_ELEMENT_ID channel_configuration_11[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_12[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_13[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_LFE, ID_SCE,
+ ID_CPE, ID_CPE, ID_SCE, ID_CPE, ID_SCE, ID_SCE, ID_CPE, ID_NONE};
+static const MP4_ELEMENT_ID channel_configuration_14[] = {
+ ID_SCE, ID_CPE, ID_CPE, ID_LAST, ID_CPE, ID_NONE};
+
+static const MP4_ELEMENT_ID *channel_configuration_array[] = {
+ channel_configuration_0, channel_configuration_1,
+ channel_configuration_2, channel_configuration_3,
+ channel_configuration_4, channel_configuration_5,
+ channel_configuration_6, channel_configuration_7,
+ channel_configuration_8, channel_configuration_9,
+ channel_configuration_10, channel_configuration_11,
+ channel_configuration_12, channel_configuration_13,
+ channel_configuration_14};
+
+#define TP_USAC_MAX_CHANNEL_CONFIGURATION_INDEX (13)
+#define SC_CHANNEL_CONFIG_TAB_SIZE (TP_USAC_MAX_CHANNEL_CONFIGURATION_INDEX + 1)
+
+/* channel config structure used for sanity check */
+typedef struct {
+ SCHAR nCh; /* number of channels */
+ SCHAR nSCE; /* number of SCE's */
+ SCHAR nCPE; /* number of CPE's */
+ SCHAR nLFE; /* number of LFE's */
+} SC_CHANNEL_CONFIG;
+
+static const SC_CHANNEL_CONFIG sc_chan_config_tab[SC_CHANNEL_CONFIG_TAB_SIZE] =
+ {
+ /* nCh, nSCE, nCPE, nLFE, cci */
+ {0, 0, 0, 0}, /* 0 */
+ {1, 1, 0, 0}, /* 1 */
+ {2, 0, 1, 0}, /* 2 */
+ {3, 1, 1, 0}, /* 3 */
+ {4, 2, 1, 0}, /* 4 */
+ {5, 1, 2, 0}, /* 5 */
+ {6, 1, 2, 1}, /* 6 */
+ {8, 1, 3, 1}, /* 7 */
+ {2, 2, 0, 0}, /* 8 */
+ {3, 1, 1, 0}, /* 9 */
+ {4, 0, 2, 0}, /* 10 */
+ {7, 2, 2, 1}, /* 11 */
+ {8, 1, 3, 1}, /* 12 */
+ {24, 6, 8, 2} /* 13 */
+};
+
+void CProgramConfig_Reset(CProgramConfig *pPce) { pPce->elCounter = 0; }
+
+void CProgramConfig_Init(CProgramConfig *pPce) {
FDKmemclear(pPce, sizeof(CProgramConfig));
-#ifdef TP_PCE_ENABLE
pPce->SamplingFrequencyIndex = 0xf;
-#endif
}
-int CProgramConfig_IsValid ( const CProgramConfig *pPce )
-{
- return ( (pPce->isValid) ? 1 : 0);
+int CProgramConfig_IsValid(const CProgramConfig *pPce) {
+ return ((pPce->isValid) ? 1 : 0);
}
-#ifdef TP_PCE_ENABLE
-#define PCE_HEIGHT_EXT_SYNC ( 0xAC )
+#define PCE_HEIGHT_EXT_SYNC (0xAC)
/*
* Read the extension for height info.
@@ -122,16 +200,12 @@ int CProgramConfig_IsValid ( const CProgramConfig *pPce )
* -1 if the CRC failed,
* -2 if invalid HeightInfo.
*/
-static
-int CProgramConfig_ReadHeightExt(
- CProgramConfig *pPce,
- HANDLE_FDK_BITSTREAM bs,
- int * const bytesAvailable,
- const UINT alignmentAnchor
- )
-{
+static int CProgramConfig_ReadHeightExt(CProgramConfig *pPce,
+ HANDLE_FDK_BITSTREAM bs,
+ int *const bytesAvailable,
+ const UINT alignmentAnchor) {
int err = 0;
- FDK_CRCINFO crcInfo; /* CRC state info */
+ FDK_CRCINFO crcInfo; /* CRC state info */
INT crcReg;
FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
crcReg = FDKcrcStartReg(&crcInfo, bs, 0);
@@ -141,45 +215,47 @@ int CProgramConfig_ReadHeightExt(
FDK_ASSERT(bs != NULL);
FDK_ASSERT(bytesAvailable != NULL);
- if ( (startAnchor >= 24) && (*bytesAvailable >= 3)
- && (FDKreadBits(bs,8) == PCE_HEIGHT_EXT_SYNC) )
- {
+ if ((startAnchor >= 24) && (*bytesAvailable >= 3) &&
+ (FDKreadBits(bs, 8) == PCE_HEIGHT_EXT_SYNC)) {
int i;
- for (i=0; i < pPce->NumFrontChannelElements; i++)
- {
- if ((pPce->FrontElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2)) >= PC_NUM_HEIGHT_LAYER) {
+ for (i = 0; i < pPce->NumFrontChannelElements; i++) {
+ if ((pPce->FrontElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
+ PC_NUM_HEIGHT_LAYER) {
err = -2; /* height information is out of the valid range */
}
}
- for (i=0; i < pPce->NumSideChannelElements; i++)
- {
- if ((pPce->SideElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2)) >= PC_NUM_HEIGHT_LAYER) {
+ for (i = 0; i < pPce->NumSideChannelElements; i++) {
+ if ((pPce->SideElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
+ PC_NUM_HEIGHT_LAYER) {
err = -2; /* height information is out of the valid range */
}
}
- for (i=0; i < pPce->NumBackChannelElements; i++)
- {
- if ((pPce->BackElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2)) >= PC_NUM_HEIGHT_LAYER) {
+ for (i = 0; i < pPce->NumBackChannelElements; i++) {
+ if ((pPce->BackElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
+ PC_NUM_HEIGHT_LAYER) {
err = -2; /* height information is out of the valid range */
}
}
FDKbyteAlign(bs, alignmentAnchor);
FDKcrcEndReg(&crcInfo, bs, crcReg);
- if ((USHORT)FDKreadBits(bs,8) != FDKcrcGetCRC(&crcInfo)) {
+ if ((USHORT)FDKreadBits(bs, 8) != FDKcrcGetCRC(&crcInfo)) {
/* CRC failed */
err = -1;
}
- if (err!=0) {
- /* Reset whole height information in case an error occured during parsing. The return
- value ensures that pPce->isValid is set to 0 and implicit channel mapping is used. */
- FDKmemclear(pPce->FrontElementHeightInfo, sizeof(pPce->FrontElementHeightInfo));
- FDKmemclear(pPce->SideElementHeightInfo, sizeof(pPce->SideElementHeightInfo));
- FDKmemclear(pPce->BackElementHeightInfo, sizeof(pPce->BackElementHeightInfo));
+ if (err != 0) {
+ /* Reset whole height information in case an error occured during parsing.
+ The return value ensures that pPce->isValid is set to 0 and implicit
+ channel mapping is used. */
+ FDKmemclear(pPce->FrontElementHeightInfo,
+ sizeof(pPce->FrontElementHeightInfo));
+ FDKmemclear(pPce->SideElementHeightInfo,
+ sizeof(pPce->SideElementHeightInfo));
+ FDKmemclear(pPce->BackElementHeightInfo,
+ sizeof(pPce->BackElementHeightInfo));
}
- }
- else {
+ } else {
/* No valid extension data found -> restore the initial bitbuffer state */
FDKpushBack(bs, startAnchor - FDKgetValidBits(bs));
}
@@ -190,99 +266,84 @@ int CProgramConfig_ReadHeightExt(
return (err);
}
-void CProgramConfig_Read(
- CProgramConfig *pPce,
- HANDLE_FDK_BITSTREAM bs,
- UINT alignmentAnchor
- )
-{
+void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
+ UINT alignmentAnchor) {
int i, err = 0;
int commentBytes;
pPce->NumEffectiveChannels = 0;
pPce->NumChannels = 0;
- pPce->ElementInstanceTag = (UCHAR) FDKreadBits(bs,4);
- pPce->Profile = (UCHAR) FDKreadBits(bs,2);
- pPce->SamplingFrequencyIndex = (UCHAR) FDKreadBits(bs,4);
- pPce->NumFrontChannelElements = (UCHAR) FDKreadBits(bs,4);
- pPce->NumSideChannelElements = (UCHAR) FDKreadBits(bs,4);
- pPce->NumBackChannelElements = (UCHAR) FDKreadBits(bs,4);
- pPce->NumLfeChannelElements = (UCHAR) FDKreadBits(bs,2);
- pPce->NumAssocDataElements = (UCHAR) FDKreadBits(bs,3);
- pPce->NumValidCcElements = (UCHAR) FDKreadBits(bs,4);
-
- if ((pPce->MonoMixdownPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
- {
- pPce->MonoMixdownElementNumber = (UCHAR) FDKreadBits(bs,4);
+ pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4);
+ pPce->Profile = (UCHAR)FDKreadBits(bs, 2);
+ pPce->SamplingFrequencyIndex = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumFrontChannelElements = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumSideChannelElements = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumBackChannelElements = (UCHAR)FDKreadBits(bs, 4);
+ pPce->NumLfeChannelElements = (UCHAR)FDKreadBits(bs, 2);
+ pPce->NumAssocDataElements = (UCHAR)FDKreadBits(bs, 3);
+ pPce->NumValidCcElements = (UCHAR)FDKreadBits(bs, 4);
+
+ if ((pPce->MonoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
+ pPce->MonoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4);
}
- if ((pPce->StereoMixdownPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
- {
- pPce->StereoMixdownElementNumber = (UCHAR) FDKreadBits(bs,4);
+ if ((pPce->StereoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
+ pPce->StereoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4);
}
- if ((pPce->MatrixMixdownIndexPresent = (UCHAR) FDKreadBits(bs,1)) != 0)
- {
- pPce->MatrixMixdownIndex = (UCHAR) FDKreadBits(bs,2);
- pPce->PseudoSurroundEnable = (UCHAR) FDKreadBits(bs,1);
+ if ((pPce->MatrixMixdownIndexPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
+ pPce->MatrixMixdownIndex = (UCHAR)FDKreadBits(bs, 2);
+ pPce->PseudoSurroundEnable = (UCHAR)FDKreadBits(bs, 1);
}
- for (i=0; i < pPce->NumFrontChannelElements; i++)
- {
- pPce->FrontElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
- pPce->FrontElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
+ for (i = 0; i < pPce->NumFrontChannelElements; i++) {
+ pPce->FrontElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
+ pPce->FrontElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1;
}
- for (i=0; i < pPce->NumSideChannelElements; i++)
- {
- pPce->SideElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
- pPce->SideElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
+ for (i = 0; i < pPce->NumSideChannelElements; i++) {
+ pPce->SideElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
+ pPce->SideElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1;
}
- for (i=0; i < pPce->NumBackChannelElements; i++)
- {
- pPce->BackElementIsCpe[i] = (UCHAR) FDKreadBits(bs,1);
- pPce->BackElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
+ for (i = 0; i < pPce->NumBackChannelElements; i++) {
+ pPce->BackElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
+ pPce->BackElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1;
}
pPce->NumEffectiveChannels = pPce->NumChannels;
- for (i=0; i < pPce->NumLfeChannelElements; i++)
- {
- pPce->LfeElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
+ for (i = 0; i < pPce->NumLfeChannelElements; i++) {
+ pPce->LfeElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
pPce->NumChannels += 1;
}
- for (i=0; i < pPce->NumAssocDataElements; i++)
- {
- pPce->AssocDataElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
+ for (i = 0; i < pPce->NumAssocDataElements; i++) {
+ pPce->AssocDataElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
}
- for (i=0; i < pPce->NumValidCcElements; i++)
- {
- pPce->CcElementIsIndSw[i] = (UCHAR) FDKreadBits(bs,1);
- pPce->ValidCcElementTagSelect[i] = (UCHAR) FDKreadBits(bs,4);
+ for (i = 0; i < pPce->NumValidCcElements; i++) {
+ pPce->CcElementIsIndSw[i] = (UCHAR)FDKreadBits(bs, 1);
+ pPce->ValidCcElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
}
FDKbyteAlign(bs, alignmentAnchor);
- pPce->CommentFieldBytes = (UCHAR) FDKreadBits(bs,8);
+ pPce->CommentFieldBytes = (UCHAR)FDKreadBits(bs, 8);
commentBytes = pPce->CommentFieldBytes;
/* Search for height info extension and read it if available */
- err = CProgramConfig_ReadHeightExt( pPce, bs, &commentBytes, alignmentAnchor );
+ err = CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor);
- for (i=0; i < commentBytes; i++)
- {
+ for (i = 0; i < commentBytes; i++) {
UCHAR text;
- text = (UCHAR)FDKreadBits(bs,8);
+ text = (UCHAR)FDKreadBits(bs, 8);
- if (i < PC_COMMENTLENGTH)
- {
+ if (i < PC_COMMENTLENGTH) {
pPce->Comment[i] = text;
}
}
@@ -298,28 +359,29 @@ void CProgramConfig_Read(
* 1 - different but same channel configuration
* 2 - different channel configuration but same number of channels
*/
-int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
- const CProgramConfig * const pPce2 )
-{
- int result = 0; /* Innocent until proven false. */
-
- if (FDKmemcmp(pPce1, pPce2, sizeof(CProgramConfig)) != 0)
- { /* Configurations are not completely different.
- So look into details and analyse the channel configurations: */
+int CProgramConfig_Compare(const CProgramConfig *const pPce1,
+ const CProgramConfig *const pPce2) {
+ int result = 0; /* Innocent until proven false. */
+
+ if (FDKmemcmp(pPce1, pPce2, sizeof(CProgramConfig)) !=
+ 0) { /* Configurations are not completely equal.
+ So look into details and analyse the channel configurations: */
result = -1;
- if (pPce1->NumChannels == pPce2->NumChannels)
- { /* Now the logic changes. We first assume to have the same channel configuration
- and then prove if this assumption is true. */
+ if (pPce1->NumChannels ==
+ pPce2->NumChannels) { /* Now the logic changes. We first assume to have
+ the same channel configuration and then prove
+ if this assumption is true. */
result = 1;
/* Front channels */
if (pPce1->NumFrontChannelElements != pPce2->NumFrontChannelElements) {
- result = 2; /* different number of front channel elements */
+ result = 2; /* different number of front channel elements */
} else {
int el, numCh1 = 0, numCh2 = 0;
for (el = 0; el < pPce1->NumFrontChannelElements; el += 1) {
- if (pPce1->FrontElementHeightInfo[el] != pPce2->FrontElementHeightInfo[el]) {
+ if (pPce1->FrontElementHeightInfo[el] !=
+ pPce2->FrontElementHeightInfo[el]) {
result = 2; /* different height info */
break;
}
@@ -327,16 +389,17 @@ int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
numCh2 += pPce2->FrontElementIsCpe[el] ? 2 : 1;
}
if (numCh1 != numCh2) {
- result = 2; /* different number of front channels */
+ result = 2; /* different number of front channels */
}
}
/* Side channels */
if (pPce1->NumSideChannelElements != pPce2->NumSideChannelElements) {
- result = 2; /* different number of side channel elements */
+ result = 2; /* different number of side channel elements */
} else {
int el, numCh1 = 0, numCh2 = 0;
for (el = 0; el < pPce1->NumSideChannelElements; el += 1) {
- if (pPce1->SideElementHeightInfo[el] != pPce2->SideElementHeightInfo[el]) {
+ if (pPce1->SideElementHeightInfo[el] !=
+ pPce2->SideElementHeightInfo[el]) {
result = 2; /* different height info */
break;
}
@@ -344,16 +407,17 @@ int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
numCh2 += pPce2->SideElementIsCpe[el] ? 2 : 1;
}
if (numCh1 != numCh2) {
- result = 2; /* different number of side channels */
+ result = 2; /* different number of side channels */
}
}
/* Back channels */
if (pPce1->NumBackChannelElements != pPce2->NumBackChannelElements) {
- result = 2; /* different number of back channel elements */
+ result = 2; /* different number of back channel elements */
} else {
int el, numCh1 = 0, numCh2 = 0;
for (el = 0; el < pPce1->NumBackChannelElements; el += 1) {
- if (pPce1->BackElementHeightInfo[el] != pPce2->BackElementHeightInfo[el]) {
+ if (pPce1->BackElementHeightInfo[el] !=
+ pPce2->BackElementHeightInfo[el]) {
result = 2; /* different height info */
break;
}
@@ -361,12 +425,12 @@ int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
numCh2 += pPce2->BackElementIsCpe[el] ? 2 : 1;
}
if (numCh1 != numCh2) {
- result = 2; /* different number of back channels */
+ result = 2; /* different number of back channels */
}
}
/* LFE channels */
if (pPce1->NumLfeChannelElements != pPce2->NumLfeChannelElements) {
- result = 2; /* different number of lfe channels */
+ result = 2; /* different number of lfe channels */
}
/* LFEs are always SCEs so we don't need to count the channels. */
}
@@ -375,88 +439,87 @@ int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
return result;
}
-void CProgramConfig_GetDefault( CProgramConfig *pPce,
- const UINT channelConfig )
-{
+void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig) {
FDK_ASSERT(pPce != NULL);
/* Init PCE */
CProgramConfig_Init(pPce);
- pPce->Profile = 1; /* Set AAC LC because it is the only supported object type. */
+ pPce->Profile =
+ 1; /* Set AAC LC because it is the only supported object type. */
switch (channelConfig) {
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case 32: /* 7.1 side channel configuration as defined in FDK_audio.h */
- pPce->NumFrontChannelElements = 2;
- pPce->FrontElementIsCpe[0] = 0;
- pPce->FrontElementIsCpe[1] = 1;
- pPce->NumSideChannelElements = 1;
- pPce->SideElementIsCpe[0] = 1;
- pPce->NumBackChannelElements = 1;
- pPce->BackElementIsCpe[0] = 1;
- pPce->NumLfeChannelElements = 1;
- pPce->NumChannels = 8;
- pPce->NumEffectiveChannels = 7;
- pPce->isValid = 1;
- break;
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case 12: /* 3/0/4.1ch surround back */
- pPce->BackElementIsCpe[1] = 1;
- pPce->NumChannels += 1;
- pPce->NumEffectiveChannels += 1;
- case 11: /* 3/0/3.1ch */
- pPce->NumFrontChannelElements += 2;
- pPce->FrontElementIsCpe[0] = 0;
- pPce->FrontElementIsCpe[1] = 1;
- pPce->NumBackChannelElements += 2;
- pPce->BackElementIsCpe[0] = 1;
- pPce->BackElementIsCpe[1] += 0;
- pPce->NumLfeChannelElements += 1;
- pPce->NumChannels += 7;
- pPce->NumEffectiveChannels += 6;
- pPce->isValid = 1;
- break;
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case 14: /* 2/0/0-3/0/2-0.1ch front height */
- pPce->FrontElementHeightInfo[2] = 1; /* Top speaker */
- case 7: /* 5/0/2.1ch front */
- pPce->NumFrontChannelElements += 1;
- pPce->FrontElementIsCpe[2] = 1;
- pPce->NumChannels += 2;
- pPce->NumEffectiveChannels += 2;
- case 6: /* 3/0/2.1ch */
- pPce->NumLfeChannelElements += 1;
- pPce->NumChannels += 1;
- case 5: /* 3/0/2.0ch */
- case 4: /* 3/0/1.0ch */
- pPce->NumBackChannelElements += 1;
- pPce->BackElementIsCpe[0] = (channelConfig>4) ? 1 : 0;
- pPce->NumChannels += (channelConfig>4) ? 2 : 1;
- pPce->NumEffectiveChannels += (channelConfig>4) ? 2 : 1;
- case 3: /* 3/0/0.0ch */
- pPce->NumFrontChannelElements += 1;
- pPce->FrontElementIsCpe[1] = 1;
- pPce->NumChannels += 2;
- pPce->NumEffectiveChannels += 2;
- case 1: /* 1/0/0.0ch */
- pPce->NumFrontChannelElements += 1;
- pPce->FrontElementIsCpe[0] = 0;
- pPce->NumChannels += 1;
- pPce->NumEffectiveChannels += 1;
- pPce->isValid = 1;
- break;
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- case 2: /* 2/0/0.ch */
- pPce->NumFrontChannelElements = 1;
- pPce->FrontElementIsCpe[0] = 1;
- pPce->NumChannels += 2;
- pPce->NumEffectiveChannels += 2;
- pPce->isValid = 1;
- break;
- /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- default:
- pPce->isValid = 0; /* To be explicit! */
- break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ case 32: /* 7.1 side channel configuration as defined in FDK_audio.h */
+ pPce->NumFrontChannelElements = 2;
+ pPce->FrontElementIsCpe[0] = 0;
+ pPce->FrontElementIsCpe[1] = 1;
+ pPce->NumSideChannelElements = 1;
+ pPce->SideElementIsCpe[0] = 1;
+ pPce->NumBackChannelElements = 1;
+ pPce->BackElementIsCpe[0] = 1;
+ pPce->NumLfeChannelElements = 1;
+ pPce->NumChannels = 8;
+ pPce->NumEffectiveChannels = 7;
+ pPce->isValid = 1;
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ case 12: /* 3/0/4.1ch surround back */
+ pPce->BackElementIsCpe[1] = 1;
+ pPce->NumChannels += 1;
+ pPce->NumEffectiveChannels += 1;
+ case 11: /* 3/0/3.1ch */
+ pPce->NumFrontChannelElements += 2;
+ pPce->FrontElementIsCpe[0] = 0;
+ pPce->FrontElementIsCpe[1] = 1;
+ pPce->NumBackChannelElements += 2;
+ pPce->BackElementIsCpe[0] = 1;
+ pPce->BackElementIsCpe[1] += 0;
+ pPce->NumLfeChannelElements += 1;
+ pPce->NumChannels += 7;
+ pPce->NumEffectiveChannels += 6;
+ pPce->isValid = 1;
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ case 14: /* 2/0/0-3/0/2-0.1ch front height */
+ pPce->FrontElementHeightInfo[2] = 1; /* Top speaker */
+ case 7: /* 5/0/2.1ch front */
+ pPce->NumFrontChannelElements += 1;
+ pPce->FrontElementIsCpe[2] = 1;
+ pPce->NumChannels += 2;
+ pPce->NumEffectiveChannels += 2;
+ case 6: /* 3/0/2.1ch */
+ pPce->NumLfeChannelElements += 1;
+ pPce->NumChannels += 1;
+ case 5: /* 3/0/2.0ch */
+ case 4: /* 3/0/1.0ch */
+ pPce->NumBackChannelElements += 1;
+ pPce->BackElementIsCpe[0] = (channelConfig > 4) ? 1 : 0;
+ pPce->NumChannels += (channelConfig > 4) ? 2 : 1;
+ pPce->NumEffectiveChannels += (channelConfig > 4) ? 2 : 1;
+ case 3: /* 3/0/0.0ch */
+ pPce->NumFrontChannelElements += 1;
+ pPce->FrontElementIsCpe[1] = 1;
+ pPce->NumChannels += 2;
+ pPce->NumEffectiveChannels += 2;
+ case 1: /* 1/0/0.0ch */
+ pPce->NumFrontChannelElements += 1;
+ pPce->FrontElementIsCpe[0] = 0;
+ pPce->NumChannels += 1;
+ pPce->NumEffectiveChannels += 1;
+ pPce->isValid = 1;
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ case 2: /* 2/0/0.ch */
+ pPce->NumFrontChannelElements = 1;
+ pPce->FrontElementIsCpe[0] = 1;
+ pPce->NumChannels += 2;
+ pPce->NumEffectiveChannels += 2;
+ pPce->isValid = 1;
+ break;
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ default:
+ pPce->isValid = 0; /* To be explicit! */
+ break;
}
if (pPce->isValid) {
@@ -464,13 +527,16 @@ void CProgramConfig_GetDefault( CProgramConfig *pPce,
int el, elTagSce = 0, elTagCpe = 0;
for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
- pPce->FrontElementTagSelect[el] = (pPce->FrontElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
+ pPce->FrontElementTagSelect[el] =
+ (pPce->FrontElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
}
for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
- pPce->SideElementTagSelect[el] = (pPce->SideElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
+ pPce->SideElementTagSelect[el] =
+ (pPce->SideElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
}
for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
- pPce->BackElementTagSelect[el] = (pPce->BackElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
+ pPce->BackElementTagSelect[el] =
+ (pPce->BackElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
}
elTagSce = 0;
for (el = 0; el < pPce->NumLfeChannelElements; el += 1) {
@@ -478,30 +544,26 @@ void CProgramConfig_GetDefault( CProgramConfig *pPce,
}
}
}
-#endif /* TP_PCE_ENABLE */
/**
- * \brief get implicit audio channel type for given channelConfig and MPEG ordered channel index
+ * \brief get implicit audio channel type for given channelConfig and MPEG
+ * ordered channel index
* \param channelConfig MPEG channelConfiguration from 1 upto 14
* \param index MPEG channel order index
* \return audio channel type.
*/
-static
-void getImplicitAudioChannelTypeAndIndex(
- AUDIO_CHANNEL_TYPE *chType,
- UCHAR *chIndex,
- UINT channelConfig,
- UINT index
- )
-{
+static void getImplicitAudioChannelTypeAndIndex(AUDIO_CHANNEL_TYPE *chType,
+ UCHAR *chIndex,
+ UINT channelConfig,
+ UINT index) {
if (index < 3) {
*chType = ACT_FRONT;
*chIndex = index;
} else {
switch (channelConfig) {
- case 4: /* SCE, CPE, SCE */
- case 5: /* SCE, CPE, CPE */
- case 6: /* SCE, CPE, CPE, LFE */
+ case 4: /* SCE, CPE, SCE */
+ case 5: /* SCE, CPE, CPE */
+ case 6: /* SCE, CPE, CPE, LFE */
switch (index) {
case 3:
case 4:
@@ -514,7 +576,7 @@ void getImplicitAudioChannelTypeAndIndex(
break;
}
break;
- case 7: /* SCE,CPE,CPE,CPE,LFE */
+ case 7: /* SCE,CPE,CPE,CPE,LFE */
switch (index) {
case 3:
case 4:
@@ -532,7 +594,7 @@ void getImplicitAudioChannelTypeAndIndex(
break;
}
break;
- case 11: /* SCE,CPE,CPE,SCE,LFE */
+ case 11: /* SCE,CPE,CPE,SCE,LFE */
if (index < 6) {
*chType = ACT_BACK;
*chIndex = index - 3;
@@ -541,7 +603,7 @@ void getImplicitAudioChannelTypeAndIndex(
*chIndex = 0;
}
break;
- case 12: /* SCE,CPE,CPE,CPE,LFE */
+ case 12: /* SCE,CPE,CPE,CPE,LFE */
if (index < 7) {
*chType = ACT_BACK;
*chIndex = index - 3;
@@ -550,7 +612,7 @@ void getImplicitAudioChannelTypeAndIndex(
*chIndex = 0;
}
break;
- case 14: /* SCE,CPE,CPE,LFE,CPE */
+ case 14: /* SCE,CPE,CPE,LFE,CPE */
switch (index) {
case 3:
case 4:
@@ -564,7 +626,7 @@ void getImplicitAudioChannelTypeAndIndex(
case 6:
case 7:
*chType = ACT_FRONT_TOP;
- *chIndex = index - 6; /* handle the top layer independently */
+ *chIndex = index - 6; /* handle the top layer independently */
break;
}
break;
@@ -575,436 +637,574 @@ void getImplicitAudioChannelTypeAndIndex(
}
}
-int CProgramConfig_LookupElement(
- CProgramConfig *pPce,
- UINT channelConfig,
- const UINT tag,
- const UINT channelIdx,
- UCHAR chMapping[],
- AUDIO_CHANNEL_TYPE chType[],
- UCHAR chIndex[],
- UCHAR *elMapping,
- MP4_ELEMENT_ID elList[],
- MP4_ELEMENT_ID elType
- )
-{
- if (channelConfig > 0)
- {
+int CProgramConfig_LookupElement(CProgramConfig *pPce, UINT channelConfig,
+ const UINT tag, const UINT channelIdx,
+ UCHAR chMapping[], AUDIO_CHANNEL_TYPE chType[],
+ UCHAR chIndex[], const UINT chDescrLen,
+ UCHAR *elMapping, MP4_ELEMENT_ID elList[],
+ MP4_ELEMENT_ID elType) {
+ if (channelConfig > 0) {
/* Constant channel mapping must have
been set during initialization. */
- if ( elType == ID_SCE
- || elType == ID_CPE
- || elType == ID_LFE )
- {
+ if (IS_CHANNEL_ELEMENT(elType)) {
*elMapping = pPce->elCounter;
- if (elList[pPce->elCounter] != elType) {
+ if (elList[pPce->elCounter] != elType &&
+ !IS_USAC_CHANNEL_ELEMENT(elType)) {
/* Not in the list */
- if ( (channelConfig == 2) && (elType == ID_SCE) )
- { /* This scenario occurs with HE-AAC v2 streams of buggy encoders.
- Due to other decoder implementations decoding of these kind of streams is desired. */
+ if ((channelConfig == 2) &&
+ (elType == ID_SCE)) { /* This scenario occurs with HE-AAC v2 streams
+ of buggy encoders. In other decoder
+ implementations decoding of this kind of
+ streams is desired. */
channelConfig = 1;
+ } else if ((elList[pPce->elCounter] == ID_LFE) &&
+ (elType ==
+ ID_SCE)) { /* Decode bitstreams which wrongly use ID_SCE
+ instead of ID_LFE element type. */
+ ;
} else {
return 0;
}
}
/* Assume all front channels */
- getImplicitAudioChannelTypeAndIndex(&chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
- if (elType == ID_CPE) {
- chType[channelIdx+1] = chType[channelIdx];
- chIndex[channelIdx+1] = chIndex[channelIdx]+1;
+ getImplicitAudioChannelTypeAndIndex(
+ &chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
+ if (elType == ID_CPE || elType == ID_USAC_CPE) {
+ chType[channelIdx + 1] = chType[channelIdx];
+ chIndex[channelIdx + 1] = chIndex[channelIdx] + 1;
}
pPce->elCounter++;
}
/* Accept all non-channel elements, too. */
return 1;
- }
- else
- {
-#ifdef TP_PCE_ENABLE
- if (!pPce->isValid)
-#endif /* TP_PCE_ENABLE */
- {
+ } else {
+ if ((!pPce->isValid) || (pPce->NumChannels > chDescrLen)) {
/* Implicit channel mapping. */
- if ( elType == ID_SCE
- || elType == ID_CPE
- || elType == ID_LFE )
- {
+ if (IS_USAC_CHANNEL_ELEMENT(elType)) {
+ *elMapping = pPce->elCounter++;
+ } else if (IS_MP4_CHANNEL_ELEMENT(elType)) {
/* Store all channel element IDs */
elList[pPce->elCounter] = elType;
*elMapping = pPce->elCounter++;
}
- }
-#ifdef TP_PCE_ENABLE
- else {
+ } else {
/* Accept the additional channel(s), only if the tag is in the lists */
int isCpe = 0, i;
/* Element counter */
int ec[PC_NUM_HEIGHT_LAYER] = {0};
/* Channel counters */
int cc[PC_NUM_HEIGHT_LAYER] = {0};
- int fc[PC_NUM_HEIGHT_LAYER] = {0};
- int sc[PC_NUM_HEIGHT_LAYER] = {0};
- int bc[PC_NUM_HEIGHT_LAYER] = {0};
- int lc = 0;;
+ int fc[PC_NUM_HEIGHT_LAYER] = {0}; /* front channel counter */
+ int sc[PC_NUM_HEIGHT_LAYER] = {0}; /* side channel counter */
+ int bc[PC_NUM_HEIGHT_LAYER] = {0}; /* back channel counter */
+ int lc = 0; /* lfe channel counter */
/* General MPEG (PCE) composition rules:
- Over all:
- <normal height channels><top height channels><bottom height channels>
+ <normal height channels><top height channels><bottom height
+ channels>
- Within each height layer:
<front channels><side channels><back channels>
- Exception:
- The LFE channels have no height info and thus they are arranged at the very
- end of the normal height layer channels.
+ The LFE channels have no height info and thus they are arranged at
+ the very end of the normal height layer channels.
*/
- switch (elType)
- {
- case ID_CPE:
- isCpe = 1;
- case ID_SCE:
- /* search in front channels */
- for (i = 0; i < pPce->NumFrontChannelElements; i++) {
- int heightLayer = pPce->FrontElementHeightInfo[i];
- if (isCpe == pPce->FrontElementIsCpe[i] && pPce->FrontElementTagSelect[i] == tag) {
- int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
- AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_FRONT);
- for (h = heightLayer-1; h >= 0; h-=1) {
- int el;
- /* Count front channels/elements */
- for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
- if (pPce->FrontElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ switch (elType) {
+ case ID_CPE:
+ isCpe = 1;
+ case ID_SCE:
+ /* search in front channels */
+ for (i = 0; i < pPce->NumFrontChannelElements; i++) {
+ int heightLayer = pPce->FrontElementHeightInfo[i];
+ if (isCpe == pPce->FrontElementIsCpe[i] &&
+ pPce->FrontElementTagSelect[i] == tag) {
+ int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
+ AUDIO_CHANNEL_TYPE aChType =
+ (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_FRONT);
+ for (h = heightLayer - 1; h >= 0; h -= 1) {
+ int el;
+ /* Count front channels/elements */
+ for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
+ if (pPce->FrontElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ }
}
- }
- /* Count side channels/elements */
- for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
- if (pPce->SideElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ /* Count side channels/elements */
+ for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
+ if (pPce->SideElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ }
}
- }
- /* Count back channels/elements */
- for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
- if (pPce->BackElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ /* Count back channels/elements */
+ for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
+ if (pPce->BackElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ if (h == 0) { /* normal height */
+ elIdx += pPce->NumLfeChannelElements;
+ chIdx += pPce->NumLfeChannelElements;
}
}
- if (h == 0) { /* normal height */
- elIdx += pPce->NumLfeChannelElements;
- chIdx += pPce->NumLfeChannelElements;
+ chMapping[chIdx] = channelIdx;
+ chType[chIdx] = aChType;
+ chIndex[chIdx] = fc[heightLayer];
+ if (isCpe) {
+ chMapping[chIdx + 1] = channelIdx + 1;
+ chType[chIdx + 1] = aChType;
+ chIndex[chIdx + 1] = fc[heightLayer] + 1;
}
+ *elMapping = elIdx;
+ return 1;
}
- chMapping[chIdx] = channelIdx;
- chType[chIdx] = aChType;
- chIndex[chIdx] = fc[heightLayer];
- if (isCpe) {
- chMapping[chIdx+1] = channelIdx+1;
- chType[chIdx+1] = aChType;
- chIndex[chIdx+1] = fc[heightLayer]+1;
+ ec[heightLayer] += 1;
+ if (pPce->FrontElementIsCpe[i]) {
+ cc[heightLayer] += 2;
+ fc[heightLayer] += 2;
+ } else {
+ cc[heightLayer] += 1;
+ fc[heightLayer] += 1;
}
- *elMapping = elIdx;
- return 1;
- }
- ec[heightLayer] += 1;
- if (pPce->FrontElementIsCpe[i]) {
- cc[heightLayer] += 2;
- fc[heightLayer] += 2;
- } else {
- cc[heightLayer] += 1;
- fc[heightLayer] += 1;
}
- }
- /* search in side channels */
- for (i = 0; i < pPce->NumSideChannelElements; i++) {
- int heightLayer = pPce->SideElementHeightInfo[i];
- if (isCpe == pPce->SideElementIsCpe[i] && pPce->SideElementTagSelect[i] == tag) {
- int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
- AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_SIDE);
- for (h = heightLayer-1; h >= 0; h-=1) {
- int el;
- /* Count front channels/elements */
- for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
- if (pPce->FrontElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ /* search in side channels */
+ for (i = 0; i < pPce->NumSideChannelElements; i++) {
+ int heightLayer = pPce->SideElementHeightInfo[i];
+ if (isCpe == pPce->SideElementIsCpe[i] &&
+ pPce->SideElementTagSelect[i] == tag) {
+ int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
+ AUDIO_CHANNEL_TYPE aChType =
+ (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_SIDE);
+ for (h = heightLayer - 1; h >= 0; h -= 1) {
+ int el;
+ /* Count front channels/elements */
+ for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
+ if (pPce->FrontElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ }
}
- }
- /* Count side channels/elements */
- for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
- if (pPce->SideElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ /* Count side channels/elements */
+ for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
+ if (pPce->SideElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ }
}
- }
- /* Count back channels/elements */
- for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
- if (pPce->BackElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ /* Count back channels/elements */
+ for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
+ if (pPce->BackElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ if (h ==
+ 0) { /* LFE channels belong to the normal height layer */
+ elIdx += pPce->NumLfeChannelElements;
+ chIdx += pPce->NumLfeChannelElements;
}
}
- if (h == 0) { /* LFE channels belong to the normal height layer */
- elIdx += pPce->NumLfeChannelElements;
- chIdx += pPce->NumLfeChannelElements;
+ chMapping[chIdx] = channelIdx;
+ chType[chIdx] = aChType;
+ chIndex[chIdx] = sc[heightLayer];
+ if (isCpe) {
+ chMapping[chIdx + 1] = channelIdx + 1;
+ chType[chIdx + 1] = aChType;
+ chIndex[chIdx + 1] = sc[heightLayer] + 1;
}
+ *elMapping = elIdx;
+ return 1;
}
- chMapping[chIdx] = channelIdx;
- chType[chIdx] = aChType;
- chIndex[chIdx] = sc[heightLayer];
- if (isCpe) {
- chMapping[chIdx+1] = channelIdx+1;
- chType[chIdx+1] = aChType;
- chIndex[chIdx+1] = sc[heightLayer]+1;
+ ec[heightLayer] += 1;
+ if (pPce->SideElementIsCpe[i]) {
+ cc[heightLayer] += 2;
+ sc[heightLayer] += 2;
+ } else {
+ cc[heightLayer] += 1;
+ sc[heightLayer] += 1;
}
- *elMapping = elIdx;
- return 1;
- }
- ec[heightLayer] += 1;
- if (pPce->SideElementIsCpe[i]) {
- cc[heightLayer] += 2;
- sc[heightLayer] += 2;
- } else {
- cc[heightLayer] += 1;
- sc[heightLayer] += 1;
}
- }
- /* search in back channels */
- for (i = 0; i < pPce->NumBackChannelElements; i++) {
- int heightLayer = pPce->BackElementHeightInfo[i];
- if (isCpe == pPce->BackElementIsCpe[i] && pPce->BackElementTagSelect[i] == tag) {
- int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
- AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_BACK);
- for (h = heightLayer-1; h >= 0; h-=1) {
- int el;
- /* Count front channels/elements */
- for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
- if (pPce->FrontElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ /* search in back channels */
+ for (i = 0; i < pPce->NumBackChannelElements; i++) {
+ int heightLayer = pPce->BackElementHeightInfo[i];
+ if (isCpe == pPce->BackElementIsCpe[i] &&
+ pPce->BackElementTagSelect[i] == tag) {
+ int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
+ AUDIO_CHANNEL_TYPE aChType =
+ (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_BACK);
+ for (h = heightLayer - 1; h >= 0; h -= 1) {
+ int el;
+ /* Count front channels/elements */
+ for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
+ if (pPce->FrontElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
+ }
}
- }
- /* Count side channels/elements */
- for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
- if (pPce->SideElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ /* Count side channels/elements */
+ for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
+ if (pPce->SideElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
+ }
}
- }
- /* Count back channels/elements */
- for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
- if (pPce->BackElementHeightInfo[el] == h) {
- elIdx += 1;
- chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ /* Count back channels/elements */
+ for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
+ if (pPce->BackElementHeightInfo[el] == h) {
+ elIdx += 1;
+ chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
+ }
+ }
+ if (h == 0) { /* normal height */
+ elIdx += pPce->NumLfeChannelElements;
+ chIdx += pPce->NumLfeChannelElements;
}
}
- if (h == 0) { /* normal height */
- elIdx += pPce->NumLfeChannelElements;
- chIdx += pPce->NumLfeChannelElements;
+ chMapping[chIdx] = channelIdx;
+ chType[chIdx] = aChType;
+ chIndex[chIdx] = bc[heightLayer];
+ if (isCpe) {
+ chMapping[chIdx + 1] = channelIdx + 1;
+ chType[chIdx + 1] = aChType;
+ chIndex[chIdx + 1] = bc[heightLayer] + 1;
}
+ *elMapping = elIdx;
+ return 1;
}
- chMapping[chIdx] = channelIdx;
- chType[chIdx] = aChType;
- chIndex[chIdx] = bc[heightLayer];
- if (isCpe) {
- chMapping[chIdx+1] = channelIdx+1;
- chType[chIdx+1] = aChType;
- chIndex[chIdx+1] = bc[heightLayer]+1;
+ ec[heightLayer] += 1;
+ if (pPce->BackElementIsCpe[i]) {
+ cc[heightLayer] += 2;
+ bc[heightLayer] += 2;
+ } else {
+ cc[heightLayer] += 1;
+ bc[heightLayer] += 1;
}
- *elMapping = elIdx;
- return 1;
}
- ec[heightLayer] += 1;
- if (pPce->BackElementIsCpe[i]) {
- cc[heightLayer] += 2;
- bc[heightLayer] += 2;
- } else {
- cc[heightLayer] += 1;
- bc[heightLayer] += 1;
+ break;
+
+ case ID_LFE: { /* Unfortunately we have to go through all normal height
+ layer elements to get the position of the LFE
+ channels. Start with counting the front
+ channels/elements at normal height */
+ for (i = 0; i < pPce->NumFrontChannelElements; i += 1) {
+ int heightLayer = pPce->FrontElementHeightInfo[i];
+ ec[heightLayer] += 1;
+ cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1;
}
- }
- break;
+ /* Count side channels/elements at normal height */
+ for (i = 0; i < pPce->NumSideChannelElements; i += 1) {
+ int heightLayer = pPce->SideElementHeightInfo[i];
+ ec[heightLayer] += 1;
+ cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1;
+ }
+ /* Count back channels/elements at normal height */
+ for (i = 0; i < pPce->NumBackChannelElements; i += 1) {
+ int heightLayer = pPce->BackElementHeightInfo[i];
+ ec[heightLayer] += 1;
+ cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1;
+ }
+
+ /* search in lfe channels */
+ for (i = 0; i < pPce->NumLfeChannelElements; i++) {
+ int elIdx =
+ ec[0]; /* LFE channels belong to the normal height layer */
+ int chIdx = cc[0];
+ if (pPce->LfeElementTagSelect[i] == tag) {
+ chMapping[chIdx] = channelIdx;
+ *elMapping = elIdx;
+ chType[chIdx] = ACT_LFE;
+ chIndex[chIdx] = lc;
+ return 1;
+ }
+ ec[0] += 1;
+ cc[0] += 1;
+ lc += 1;
+ }
+ } break;
+
+ /* Non audio elements */
+ case ID_CCE:
+ /* search in cce channels */
+ for (i = 0; i < pPce->NumValidCcElements; i++) {
+ if (pPce->ValidCcElementTagSelect[i] == tag) {
+ return 1;
+ }
+ }
+ break;
+ case ID_DSE:
+ /* search associated data elements */
+ for (i = 0; i < pPce->NumAssocDataElements; i++) {
+ if (pPce->AssocDataElementTagSelect[i] == tag) {
+ return 1;
+ }
+ }
+ break;
+ default:
+ return 0;
+ }
+ return 0; /* not found in any list */
+ }
+ }
- case ID_LFE:
- { /* Unfortunately we have to go through all normal height
- layer elements to get the position of the LFE channels.
- Start with counting the front channels/elements at normal height */
- for (i = 0; i < pPce->NumFrontChannelElements; i+=1) {
- int heightLayer = pPce->FrontElementHeightInfo[i];
- ec[heightLayer] += 1;
- cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1;
+ return 1;
+}
+
+#define SPEAKER_PLANE_NORMAL 0
+#define SPEAKER_PLANE_TOP 1
+#define SPEAKER_PLANE_BOTTOM 2
+
+void CProgramConfig_GetChannelDescription(const UINT chConfig,
+ const CProgramConfig *pPce,
+ AUDIO_CHANNEL_TYPE chType[],
+ UCHAR chIndex[]) {
+ FDK_ASSERT(chType != NULL);
+ FDK_ASSERT(chIndex != NULL);
+
+ if ((chConfig == 0) && (pPce != NULL)) {
+ if (pPce->isValid) {
+ int spkPlane, chIdx = 0;
+ for (spkPlane = SPEAKER_PLANE_NORMAL; spkPlane <= SPEAKER_PLANE_BOTTOM;
+ spkPlane += 1) {
+ int elIdx, grpChIdx = 0;
+ for (elIdx = 0; elIdx < pPce->NumFrontChannelElements; elIdx += 1) {
+ if (pPce->FrontElementHeightInfo[elIdx] == spkPlane) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_FRONT);
+ chIndex[chIdx++] = grpChIdx++;
+ if (pPce->FrontElementIsCpe[elIdx]) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_FRONT);
+ chIndex[chIdx++] = grpChIdx++;
+ }
+ }
}
- /* Count side channels/elements at normal height */
- for (i = 0; i < pPce->NumSideChannelElements; i+=1) {
- int heightLayer = pPce->SideElementHeightInfo[i];
- ec[heightLayer] += 1;
- cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1;
+ grpChIdx = 0;
+ for (elIdx = 0; elIdx < pPce->NumSideChannelElements; elIdx += 1) {
+ if (pPce->SideElementHeightInfo[elIdx] == spkPlane) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_SIDE);
+ chIndex[chIdx++] = grpChIdx++;
+ if (pPce->SideElementIsCpe[elIdx]) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_SIDE);
+ chIndex[chIdx++] = grpChIdx++;
+ }
+ }
}
- /* Count back channels/elements at normal height */
- for (i = 0; i < pPce->NumBackChannelElements; i+=1) {
- int heightLayer = pPce->BackElementHeightInfo[i];
- ec[heightLayer] += 1;
- cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1;
+ grpChIdx = 0;
+ for (elIdx = 0; elIdx < pPce->NumBackChannelElements; elIdx += 1) {
+ if (pPce->BackElementHeightInfo[elIdx] == spkPlane) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_BACK);
+ chIndex[chIdx++] = grpChIdx++;
+ if (pPce->BackElementIsCpe[elIdx]) {
+ chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_BACK);
+ chIndex[chIdx++] = grpChIdx++;
+ }
+ }
}
-
- /* search in lfe channels */
- for (i = 0; i < pPce->NumLfeChannelElements; i++) {
- int elIdx = ec[0]; /* LFE channels belong to the normal height layer */
- int chIdx = cc[0];
- if ( pPce->LfeElementTagSelect[i] == tag ) {
- chMapping[chIdx] = channelIdx;
- *elMapping = elIdx;
+ grpChIdx = 0;
+ if (spkPlane == SPEAKER_PLANE_NORMAL) {
+ for (elIdx = 0; elIdx < pPce->NumLfeChannelElements; elIdx += 1) {
chType[chIdx] = ACT_LFE;
- chIndex[chIdx] = lc;
- return 1;
+ chIndex[chIdx++] = grpChIdx++;
}
- ec[0] += 1;
- cc[0] += 1;
- lc += 1;
}
- } break;
+ }
+ }
+ } else {
+ int chIdx;
+ for (chIdx = 0; chIdx < getNumberOfTotalChannels(chConfig); chIdx += 1) {
+ getImplicitAudioChannelTypeAndIndex(&chType[chIdx], &chIndex[chIdx],
+ chConfig, chIdx);
+ }
+ }
+}
- /* Non audio elements */
- case ID_CCE:
- /* search in cce channels */
- for (i = 0; i < pPce->NumValidCcElements; i++) {
- if (pPce->ValidCcElementTagSelect[i] == tag) {
- return 1;
- }
- }
- break;
- case ID_DSE:
- /* search associated data elements */
- for (i = 0; i < pPce->NumAssocDataElements; i++) {
- if (pPce->AssocDataElementTagSelect[i] == tag) {
- return 1;
- }
+int CProgramConfig_GetPceChMap(const CProgramConfig *pPce, UCHAR pceChMap[],
+ const UINT pceChMapLen) {
+ const UCHAR *nElements = &pPce->NumFrontChannelElements;
+ const UCHAR *elHeight[3], *elIsCpe[3];
+ unsigned chIdx, plane, grp, offset, totCh[3], numCh[3][4];
+
+ FDK_ASSERT(pPce != NULL);
+ FDK_ASSERT(pceChMap != NULL);
+
+ /* Init counter: */
+ FDKmemclear(totCh, 3 * sizeof(unsigned));
+ FDKmemclear(numCh, 3 * 4 * sizeof(unsigned));
+
+ /* Analyse PCE: */
+ elHeight[0] = pPce->FrontElementHeightInfo;
+ elIsCpe[0] = pPce->FrontElementIsCpe;
+ elHeight[1] = pPce->SideElementHeightInfo;
+ elIsCpe[1] = pPce->SideElementIsCpe;
+ elHeight[2] = pPce->BackElementHeightInfo;
+ elIsCpe[2] = pPce->BackElementIsCpe;
+
+ for (plane = 0; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) {
+ for (grp = 0; grp < 3; grp += 1) { /* front, side, back */
+ unsigned el;
+ for (el = 0; el < nElements[grp]; el += 1) {
+ if (elHeight[grp][el] == plane) {
+ unsigned elCh = elIsCpe[grp][el] ? 2 : 1;
+ numCh[plane][grp] += elCh;
+ totCh[plane] += elCh;
}
- break;
- default:
- return 0;
}
- return 0; /* not found in any list */
}
-#endif /* TP_PCE_ENABLE */
+ if (plane == SPEAKER_PLANE_NORMAL) {
+ unsigned elCh = pPce->NumLfeChannelElements;
+ numCh[plane][grp] += elCh;
+ totCh[plane] += elCh;
+ }
+ }
+ /* Sanity checks: */
+ chIdx = totCh[SPEAKER_PLANE_NORMAL] + totCh[SPEAKER_PLANE_TOP] +
+ totCh[SPEAKER_PLANE_BOTTOM];
+ if (chIdx > pceChMapLen) {
+ return -1;
}
- return 1;
+ /* Create map: */
+ offset = grp = 0;
+ unsigned grpThresh = numCh[SPEAKER_PLANE_NORMAL][grp];
+ for (chIdx = 0; chIdx < totCh[SPEAKER_PLANE_NORMAL]; chIdx += 1) {
+ while ((chIdx >= grpThresh) && (grp < 3)) {
+ offset += numCh[1][grp] + numCh[2][grp];
+ grp += 1;
+ grpThresh += numCh[SPEAKER_PLANE_NORMAL][grp];
+ }
+ pceChMap[chIdx] = chIdx + offset;
+ }
+ offset = 0;
+ for (grp = 0; grp < 4; grp += 1) { /* front, side, back and lfe */
+ offset += numCh[SPEAKER_PLANE_NORMAL][grp];
+ for (plane = SPEAKER_PLANE_TOP; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) {
+ unsigned mapCh;
+ for (mapCh = 0; mapCh < numCh[plane][grp]; mapCh += 1) {
+ pceChMap[chIdx++] = offset;
+ offset += 1;
+ }
+ }
+ }
+ return 0;
}
-#ifdef TP_PCE_ENABLE
-int CProgramConfig_GetElementTable(
- const CProgramConfig *pPce,
- MP4_ELEMENT_ID elList[],
- const INT elListSize,
- UCHAR *pChMapIdx
- )
-{
+int CProgramConfig_GetElementTable(const CProgramConfig *pPce,
+ MP4_ELEMENT_ID elList[],
+ const INT elListSize, UCHAR *pChMapIdx) {
int i, el = 0;
FDK_ASSERT(elList != NULL);
FDK_ASSERT(pChMapIdx != NULL);
+ FDK_ASSERT(pPce != NULL);
*pChMapIdx = 0;
- if ( elListSize
- < pPce->NumFrontChannelElements + pPce->NumSideChannelElements + pPce->NumBackChannelElements + pPce->NumLfeChannelElements
- )
- {
+ if ((elListSize <
+ pPce->NumFrontChannelElements + pPce->NumSideChannelElements +
+ pPce->NumBackChannelElements + pPce->NumLfeChannelElements) ||
+ (pPce->NumChannels == 0)) {
return 0;
}
- for (i=0; i < pPce->NumFrontChannelElements; i++)
- {
- elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE;
+ for (i = 0; i < pPce->NumFrontChannelElements; i += 1) {
+ elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE;
}
- for (i=0; i < pPce->NumSideChannelElements; i++)
- {
- elList[el++] = (pPce->SideElementIsCpe[i]) ? ID_CPE : ID_SCE;
+ for (i = 0; i < pPce->NumSideChannelElements; i += 1) {
+ elList[el++] = (pPce->SideElementIsCpe[i]) ? ID_CPE : ID_SCE;
}
- for (i=0; i < pPce->NumBackChannelElements; i++)
- {
- elList[el++] = (pPce->BackElementIsCpe[i]) ? ID_CPE : ID_SCE;
+ for (i = 0; i < pPce->NumBackChannelElements; i += 1) {
+ elList[el++] = (pPce->BackElementIsCpe[i]) ? ID_CPE : ID_SCE;
}
- for (i=0; i < pPce->NumLfeChannelElements; i++)
- {
+ for (i = 0; i < pPce->NumLfeChannelElements; i += 1) {
elList[el++] = ID_LFE;
}
-
/* Find an corresponding channel configuration if possible */
switch (pPce->NumChannels) {
- case 1: case 2: case 3: case 4: case 5: case 6:
- /* One and two channels have no alternatives. The other ones are mapped directly to the
- corresponding channel config. Because of legacy reasons or for lack of alternative mappings. */
- *pChMapIdx = pPce->NumChannels;
- break;
- case 7:
- {
+ case 1:
+ case 2:
+ /* One and two channels have no alternatives. */
+ *pChMapIdx = pPce->NumChannels;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ case 6: { /* Test if the number of channels can be used as channel config:
+ */
+ C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
+ /* Create a PCE for the config to test ... */
+ CProgramConfig_GetDefault(tmpPce, pPce->NumChannels);
+ /* ... and compare it with the given one. */
+ *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE))
+ ? pPce->NumChannels
+ : 0;
+ /* If compare result is 0 or 1 we can be sure that it is channel
+ * config 11. */
+ C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
+ } break;
+ case 7: {
C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
/* Create a PCE for the config to test ... */
CProgramConfig_GetDefault(tmpPce, 11);
/* ... and compare it with the given one. */
- *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce)&0xE)) ? 11 : 0;
- /* If compare result is 0 or 1 we can be sure that it is channel config 11. */
+ *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) ? 11 : 0;
+ /* If compare result is 0 or 1 we can be sure that it is channel
+ * config 11. */
C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
- }
- break;
- case 8:
- { /* Try the four possible 7.1ch configurations. One after the other. */
- UCHAR testCfg[4] = { 32, 14, 12, 7};
+ } break;
+ case 8: { /* Try the four possible 7.1ch configurations. One after the
+ other. */
+ UCHAR testCfg[4] = {32, 14, 12, 7};
C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
- for (i=0; i<4; i+=1) {
+ for (i = 0; i < 4; i += 1) {
/* Create a PCE for the config to test ... */
CProgramConfig_GetDefault(tmpPce, testCfg[i]);
/* ... and compare it with the given one. */
- if (!(CProgramConfig_Compare(pPce, tmpPce)&0xE)) {
- /* If the compare result is 0 or 1 than the two channel configurations match. */
- /* Explicit mapping of 7.1 side channel configuration to 7.1 rear channel mapping. */
- *pChMapIdx = (testCfg[i]==32) ? 12 : testCfg[i];
+ if (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) {
+ /* If the compare result is 0 or 1 than the two channel configurations
+ * match. */
+ /* Explicit mapping of 7.1 side channel configuration to 7.1 rear
+ * channel mapping. */
+ *pChMapIdx = (testCfg[i] == 32) ? 12 : testCfg[i];
}
}
C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
- }
- break;
- default:
- /* The PCE does not match any predefined channel configuration. */
- *pChMapIdx = 0;
- break;
+ } break;
+ default:
+ /* The PCE does not match any predefined channel configuration. */
+ *pChMapIdx = 0;
+ break;
}
return el;
}
-#endif
-static AUDIO_OBJECT_TYPE getAOT(HANDLE_FDK_BITSTREAM bs)
-{
+static AUDIO_OBJECT_TYPE getAOT(HANDLE_FDK_BITSTREAM bs) {
int tmp = 0;
- tmp = FDKreadBits(bs,5);
+ tmp = FDKreadBits(bs, 5);
if (tmp == AOT_ESCAPE) {
- int tmp2 = FDKreadBits(bs,6);
+ int tmp2 = FDKreadBits(bs, 6);
tmp = 32 + tmp2;
}
return (AUDIO_OBJECT_TYPE)tmp;
}
-static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits)
-{
+static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits) {
INT sampleRate;
int idx;
idx = FDKreadBits(bs, nBits);
- if( idx == (1<<nBits)-1 ) {
- if(FDKgetValidBits(bs) < 24) {
+ if (idx == (1 << nBits) - 1) {
+ if (FDKgetValidBits(bs) < 24) {
return 0;
}
- sampleRate = FDKreadBits(bs,24);
+ sampleRate = FDKreadBits(bs, 24);
} else {
sampleRate = SamplingRateTable[idx];
}
@@ -1014,132 +1214,164 @@ static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits)
return sampleRate;
}
-#ifdef TP_GA_ENABLE
-static
-TRANSPORTDEC_ERROR GaSpecificConfig_Parse( CSGaSpecificConfig *self,
- CSAudioSpecificConfig *asc,
- HANDLE_FDK_BITSTREAM bs,
- UINT ascStartAnchor )
-{
+static TRANSPORTDEC_ERROR GaSpecificConfig_Parse(CSGaSpecificConfig *self,
+ CSAudioSpecificConfig *asc,
+ HANDLE_FDK_BITSTREAM bs,
+ UINT ascStartAnchor) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
- self->m_frameLengthFlag = FDKreadBits(bs,1);
+ self->m_frameLengthFlag = FDKreadBits(bs, 1);
- self->m_dependsOnCoreCoder = FDKreadBits(bs,1);
+ self->m_dependsOnCoreCoder = FDKreadBits(bs, 1);
- if( self->m_dependsOnCoreCoder )
- self->m_coreCoderDelay = FDKreadBits(bs,14);
+ if (self->m_dependsOnCoreCoder) self->m_coreCoderDelay = FDKreadBits(bs, 14);
- self->m_extensionFlag = FDKreadBits(bs,1);
+ self->m_extensionFlag = FDKreadBits(bs, 1);
- if( asc->m_channelConfiguration == 0 ) {
+ if (asc->m_channelConfiguration == 0) {
CProgramConfig_Read(&asc->m_progrConfigElement, bs, ascStartAnchor);
}
if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
- self->m_layer = FDKreadBits(bs,3);
+ self->m_layer = FDKreadBits(bs, 3);
}
if (self->m_extensionFlag) {
if (asc->m_aot == AOT_ER_BSAC) {
- self->m_numOfSubFrame = FDKreadBits(bs,5);
- self->m_layerLength = FDKreadBits(bs,11);
+ self->m_numOfSubFrame = FDKreadBits(bs, 5);
+ self->m_layerLength = FDKreadBits(bs, 11);
}
- if ((asc->m_aot == AOT_ER_AAC_LC) || (asc->m_aot == AOT_ER_AAC_LTP) ||
- (asc->m_aot == AOT_ER_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_LD))
- {
- asc->m_vcb11Flag = FDKreadBits(bs,1); /* aacSectionDataResilienceFlag */
- asc->m_rvlcFlag = FDKreadBits(bs,1); /* aacScalefactorDataResilienceFlag */
- asc->m_hcrFlag = FDKreadBits(bs,1); /* aacSpectralDataResilienceFlag */
+ if ((asc->m_aot == AOT_ER_AAC_LC) || (asc->m_aot == AOT_ER_AAC_LTP) ||
+ (asc->m_aot == AOT_ER_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_LD)) {
+ asc->m_vcb11Flag = FDKreadBits(bs, 1); /* aacSectionDataResilienceFlag */
+ asc->m_rvlcFlag =
+ FDKreadBits(bs, 1); /* aacScalefactorDataResilienceFlag */
+ asc->m_hcrFlag = FDKreadBits(bs, 1); /* aacSpectralDataResilienceFlag */
}
- self->m_extensionFlag3 = FDKreadBits(bs,1);
-
+ self->m_extensionFlag3 = FDKreadBits(bs, 1);
}
return (ErrorStatus);
}
-#endif /* TP_GA_ENABLE */
-
-
+static INT skipSbrHeader(HANDLE_FDK_BITSTREAM hBs, int isUsac) {
+ /* Dummy parse SbrDfltHeader() */
+ INT dflt_header_extra1, dflt_header_extra2, bitsToSkip = 0;
+ if (!isUsac) {
+ bitsToSkip = 6;
+ FDKpushFor(hBs, 6); /* amp res 1, xover freq 3, reserved 2 */
+ }
+ bitsToSkip += 8;
+ FDKpushFor(hBs, 8); /* start / stop freq */
+ bitsToSkip += 2;
+ dflt_header_extra1 = FDKreadBit(hBs);
+ dflt_header_extra2 = FDKreadBit(hBs);
+ bitsToSkip += 5 * dflt_header_extra1 + 6 * dflt_header_extra2;
+ FDKpushFor(hBs, 5 * dflt_header_extra1 + 6 * dflt_header_extra2);
+
+ return bitsToSkip;
+}
-#ifdef TP_ELD_ENABLE
-
-static INT ld_sbr_header( const CSAudioSpecificConfig *asc,
- HANDLE_FDK_BITSTREAM hBs,
- CSTpCallBacks *cb )
-{
+static INT ld_sbr_header(CSAudioSpecificConfig *asc, const INT dsFactor,
+ HANDLE_FDK_BITSTREAM hBs, CSTpCallBacks *cb) {
const int channelConfiguration = asc->m_channelConfiguration;
- int i = 0;
+ int i = 0, j = 0;
INT error = 0;
-
- if (channelConfiguration == 2) {
- error = cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
- } else {
- error = cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_SCE, i++);
+ MP4_ELEMENT_ID element = ID_NONE;
+
+ /* check whether the channelConfiguration is defined in
+ * channel_configuration_array */
+ if (channelConfiguration < 0 ||
+ channelConfiguration > (INT)(sizeof(channel_configuration_array) /
+ sizeof(MP4_ELEMENT_ID **) -
+ 1)) {
+ return TRANSPORTDEC_PARSE_ERROR;
}
- switch ( channelConfiguration ) {
- case 14:
- case 12:
- case 7:
- error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
- case 6:
- case 5:
- error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
- case 3:
- error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
- break;
-
- case 11:
- error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
- case 4:
- error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
- error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_SCE, i++);
- break;
+ /* read elements of the passed channel_configuration until there is ID_NONE */
+ while ((element = channel_configuration_array[channelConfiguration][j]) !=
+ ID_NONE) {
+ if (element == ID_SCE || element == ID_CPE) {
+ error |= cb->cbSbr(
+ cb->cbSbrData, hBs, asc->m_samplingFrequency / dsFactor,
+ asc->m_extensionSamplingFrequency / dsFactor,
+ asc->m_samplesPerFrame / dsFactor, AOT_ER_AAC_ELD, element, i++, 0, 0,
+ asc->configMode, &asc->SbrConfigChanged, dsFactor);
+ if (error != TRANSPORTDEC_OK) {
+ goto bail;
+ }
+ }
+ j++;
}
-
+bail:
return error;
}
-static
-TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
- CSAudioSpecificConfig *asc,
- HANDLE_FDK_BITSTREAM hBs,
- CSTpCallBacks *cb
- )
-{
+static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
+ HANDLE_FDK_BITSTREAM hBs,
+ CSTpCallBacks *cb) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
ASC_ELD_EXT_TYPE eldExtType;
- int eldExtLen, len, cnt;
+ int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
+ sbrIndex;
+
+ unsigned char downscale_fill_nibble;
FDKmemclear(esc, sizeof(CSEldSpecificConfig));
- esc->m_frameLengthFlag = FDKreadBits(hBs, 1 );
+ esc->m_frameLengthFlag = FDKreadBits(hBs, 1);
if (esc->m_frameLengthFlag) {
asc->m_samplesPerFrame = 480;
} else {
asc->m_samplesPerFrame = 512;
}
- asc->m_vcb11Flag = FDKreadBits(hBs, 1 );
- asc->m_rvlcFlag = FDKreadBits(hBs, 1 );
- asc->m_hcrFlag = FDKreadBits(hBs, 1 );
+ asc->m_vcb11Flag = FDKreadBits(hBs, 1);
+ asc->m_rvlcFlag = FDKreadBits(hBs, 1);
+ asc->m_hcrFlag = FDKreadBits(hBs, 1);
- esc->m_sbrPresentFlag = FDKreadBits(hBs, 1 );
+ esc->m_sbrPresentFlag = FDKreadBits(hBs, 1);
if (esc->m_sbrPresentFlag == 1) {
- esc->m_sbrSamplingRate = FDKreadBits(hBs, 1 ); /* 0: single rate, 1: dual rate */
- esc->m_sbrCrcFlag = FDKreadBits(hBs, 1 );
-
- asc->m_extensionSamplingFrequency = asc->m_samplingFrequency << esc->m_sbrSamplingRate;
-
- if (cb->cbSbr != NULL){
- if ( 0 != ld_sbr_header(asc, hBs, cb) ) {
- return TRANSPORTDEC_PARSE_ERROR;
+ esc->m_sbrSamplingRate =
+ FDKreadBits(hBs, 1); /* 0: single rate, 1: dual rate */
+ esc->m_sbrCrcFlag = FDKreadBits(hBs, 1);
+
+ asc->m_extensionSamplingFrequency = asc->m_samplingFrequency
+ << esc->m_sbrSamplingRate;
+
+ if (cb->cbSbr != NULL) {
+ /* ELD reduced delay mode: LD-SBR initialization has to know the downscale
+ information. Postpone LD-SBR initialization and read ELD extension
+ information first. */
+ switch (asc->m_channelConfiguration) {
+ case 1:
+ case 2:
+ numSbrHeader = 1;
+ break;
+ case 3:
+ numSbrHeader = 2;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ numSbrHeader = 3;
+ break;
+ case 7:
+ case 11:
+ case 12:
+ case 14:
+ numSbrHeader = 4;
+ break;
+ default:
+ numSbrHeader = 0;
+ break;
+ }
+ for (sbrIndex = 0; sbrIndex < numSbrHeader; sbrIndex++) {
+ ldSbrLen += skipSbrHeader(hBs, 0);
}
} else {
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
@@ -1148,85 +1380,686 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
esc->m_useLdQmfTimeAlign = 0;
/* new ELD syntax */
+ eldExtLenSum = FDKgetValidBits(hBs);
+ esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
/* parse ExtTypeConfigData */
- while ((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4 )) != ELDEXT_TERM) {
- eldExtLen = len = FDKreadBits(hBs, 4 );
- if ( len == 0xf ) {
- len = FDKreadBits(hBs, 8 );
+ while (
+ ((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
+ ((INT)FDKgetValidBits(hBs) >= 0)) {
+ eldExtLen = len = FDKreadBits(hBs, 4);
+ if (len == 0xf) {
+ len = FDKreadBits(hBs, 8);
eldExtLen += len;
- if ( len == 0xff ) {
- len = FDKreadBits(hBs, 16 );
+ if (len == 0xff) {
+ len = FDKreadBits(hBs, 16);
eldExtLen += len;
}
}
switch (eldExtType) {
+ case ELDEXT_LDSAC:
+ esc->m_useLdQmfTimeAlign = 1;
+ if (cb->cbSsc != NULL) {
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
+ cb->cbSscData, hBs, asc->m_aot, asc->m_extensionSamplingFrequency,
+ 1, /* stereoConfigIndex */
+ -1, /* nTimeSlots: read from bitstream */
+ eldExtLen, asc->configMode, &asc->SacConfigChanged);
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ break;
+ }
+
+ /* fall-through */
default:
- for(cnt=0; cnt<eldExtLen; cnt++) {
- FDKreadBits(hBs, 8 );
+ for (cnt = 0; cnt < eldExtLen; cnt++) {
+ FDKreadBits(hBs, 8);
+ }
+ break;
+
+ case ELDEXT_DOWNSCALEINFO:
+ UCHAR tmpDownscaleFreqIdx;
+ esc->m_downscaledSamplingFrequency =
+ getSampleRate(hBs, &tmpDownscaleFreqIdx, 4);
+ if (esc->m_downscaledSamplingFrequency == 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ downscale_fill_nibble = FDKreadBits(hBs, 4);
+ if (downscale_fill_nibble != 0x0) {
+ return TRANSPORTDEC_PARSE_ERROR;
}
break;
- /* add future eld extension configs here */
}
}
-bail:
+
+ if ((INT)FDKgetValidBits(hBs) < 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ if (esc->m_sbrPresentFlag == 1 && numSbrHeader != 0) {
+ INT dsFactor = 1; /* Downscale factor must be 1 or even for SBR */
+ if (esc->m_downscaledSamplingFrequency != 0) {
+ if (asc->m_samplingFrequency % esc->m_downscaledSamplingFrequency != 0) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ dsFactor = asc->m_samplingFrequency / esc->m_downscaledSamplingFrequency;
+ if (dsFactor != 1 && (dsFactor)&1) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* SBR needs an even downscale
+ factor */
+ }
+ if (dsFactor != 1 && dsFactor != 2 && dsFactor != 4) {
+ dsFactor = 1; /* don't apply dsf for not yet supported even dsfs */
+ }
+ if ((INT)asc->m_samplesPerFrame % dsFactor != 0) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* frameSize/dsf must be an
+ integer number */
+ }
+ }
+ eldExtLenSum = eldExtLenSum - FDKgetValidBits(hBs);
+ FDKpushBack(hBs, eldExtLenSum + ldSbrLen);
+ if (0 != ld_sbr_header(asc, dsFactor, hBs, cb)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ FDKpushFor(hBs, eldExtLenSum);
+ }
return (ErrorStatus);
}
-#endif /* TP_ELD_ENABLE */
+/*
+Subroutine to store config in UCHAR buffer. Bit stream position does not change.
+*/
+static UINT StoreConfigAsBitstream(
+ HANDLE_FDK_BITSTREAM hBs, const INT configSize_bits, /* If < 0 (> 0) config
+ to read is before
+ (after) current bit
+ stream position. */
+ UCHAR *configTargetBuffer, const USHORT configTargetBufferSize_bytes) {
+ FDK_BITSTREAM usacConf;
+ UINT const nBits = fAbs(configSize_bits);
+ UINT j, tmp;
+
+ if (nBits > 8 * (UINT)configTargetBufferSize_bytes) {
+ return 1;
+ }
+ FDKmemclear(configTargetBuffer, configTargetBufferSize_bytes);
+
+ FDKinitBitStream(&usacConf, configTargetBuffer, configTargetBufferSize_bytes,
+ nBits, BS_WRITER);
+ if (configSize_bits < 0) {
+ FDKpushBack(hBs, nBits);
+ }
+ for (j = nBits; j > 31; j -= 32) {
+ tmp = FDKreadBits(hBs, 32);
+ FDKwriteBits(&usacConf, tmp, 32);
+ }
+ if (j > 0) {
+ tmp = FDKreadBits(hBs, j);
+ FDKwriteBits(&usacConf, tmp, j);
+ }
+ FDKsyncCache(&usacConf);
+ if (configSize_bits > 0) {
+ FDKpushBack(hBs, nBits);
+ }
+
+ return 0;
+}
+
+/* maps coreSbrFrameLengthIndex to coreCoderFrameLength */
+static const USHORT usacFrameLength[8] = {768, 1024, 2048, 2048, 4096, 0, 0, 0};
+/* maps coreSbrFrameLengthIndex to sbrRatioIndex */
+static const UCHAR sbrRatioIndex[8] = {0, 0, 2, 3, 1, 0, 0, 0};
+
+/*
+ subroutine for parsing extension element configuration:
+ UsacExtElementConfig() q.v. ISO/IEC FDIS 23003-3:2011(E) Table 14
+ rsv603daExtElementConfig() q.v. ISO/IEC DIS 23008-3 Table 13
+*/
+static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement,
+ HANDLE_FDK_BITSTREAM hBs,
+ const CSTpCallBacks *cb,
+ const UCHAR numSignalsInGroup,
+ const UINT coreFrameLength,
+ const int subStreamIndex,
+ const AUDIO_OBJECT_TYPE aot) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ USAC_EXT_ELEMENT_TYPE usacExtElementType =
+ (USAC_EXT_ELEMENT_TYPE)escapedValue(hBs, 4, 8, 16);
+
+ /* recurve extension elements which are invalid for USAC */
+ if (aot == AOT_USAC) {
+ switch (usacExtElementType) {
+ case ID_EXT_ELE_FILL:
+ case ID_EXT_ELE_MPEGS:
+ case ID_EXT_ELE_SAOC:
+ case ID_EXT_ELE_AUDIOPREROLL:
+ case ID_EXT_ELE_UNI_DRC:
+ break;
+ default:
+ usacExtElementType = ID_EXT_ELE_UNKNOWN;
+ break;
+ }
+ }
+
+ extElement->usacExtElementType = usacExtElementType;
+ int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16);
+ extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength;
+ INT bsAnchor;
-static
-TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb)
-{
- TP_ASC_EXTENSION_ID lastAscExt, ascExtId = ASCEXT_UNKOWN;
- INT bitsAvailable = (INT)FDKgetValidBits(bs);
+ if (FDKreadBit(hBs)) /* usacExtElementDefaultLengthPresent */
+ extElement->usacExtElementDefaultLength = escapedValue(hBs, 8, 16, 0) + 1;
+ else
+ extElement->usacExtElementDefaultLength = 0;
+
+ extElement->usacExtElementPayloadFrag = FDKreadBit(hBs);
- while (bitsAvailable >= 11)
+ bsAnchor = (INT)FDKgetValidBits(hBs);
+
+ switch (usacExtElementType) {
+ case ID_EXT_ELE_UNKNOWN:
+ case ID_EXT_ELE_FILL:
+ break;
+ case ID_EXT_ELE_AUDIOPREROLL:
+ /* No configuration element */
+ extElement->usacExtElementHasAudioPreRoll = 1;
+ break;
+ case ID_EXT_ELE_UNI_DRC: {
+ if (cb->cbUniDrc != NULL) {
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
+ cb->cbUniDrcData, hBs, usacExtElementConfigLength,
+ 0, /* uniDrcConfig */
+ subStreamIndex, 0, aot);
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ return ErrorStatus;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+ /* Adjust bit stream position. This is required because of byte alignment and
+ * unhandled extensions. */
{
- lastAscExt = ascExtId;
- ascExtId = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11);
- bitsAvailable -= 11;
+ INT left_bits = (usacExtElementConfigLength << 3) -
+ (bsAnchor - (INT)FDKgetValidBits(hBs));
+ if (left_bits >= 0) {
+ FDKpushFor(hBs, left_bits);
+ } else {
+ /* parsed too many bits */
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
- switch (ascExtId) {
- case ASCEXT_SBR: /* 0x2b7 */
- if ( (self->m_extensionAudioObjectType != AOT_SBR) && (bitsAvailable >= 5) ) {
- self->m_extensionAudioObjectType = getAOT(bs);
-
- if ( (self->m_extensionAudioObjectType == AOT_SBR)
- || (self->m_extensionAudioObjectType == AOT_ER_BSAC) )
- { /* Get SBR extension configuration */
- self->m_sbrPresentFlag = FDKreadBits(bs, 1);
- bitsAvailable -= 1;
+ return ErrorStatus;
+}
+
+/*
+ subroutine for parsing the USAC / RSVD60 configuration extension:
+ UsacConfigExtension() q.v. ISO/IEC FDIS 23003-3:2011(E) Table 15
+ rsv603daConfigExtension() q.v. ISO/IEC DIS 23008-3 Table 14
+*/
+static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
+ HANDLE_FDK_BITSTREAM hBs,
+ const CSTpCallBacks *cb) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ int numConfigExtensions;
+ CONFIG_EXT_ID usacConfigExtType;
+ int usacConfigExtLength;
+
+ numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1;
+ for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) {
+ INT nbits;
+ int loudnessInfoSetConfigExtensionPosition = FDKgetValidBits(hBs);
+ usacConfigExtType = (CONFIG_EXT_ID)escapedValue(hBs, 4, 8, 16);
+ usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16);
+
+ /* Start bit position of config extension */
+ nbits = FDKgetValidBits(hBs);
+
+ /* Return an error in case the bitbuffer fill level is too low. */
+ if (nbits < usacConfigExtLength * 8) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ switch (usacConfigExtType) {
+ case ID_CONFIG_EXT_FILL:
+ for (int i = 0; i < usacConfigExtLength; i++) {
+ if (FDKreadBits(hBs, 8) != 0xa5) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ break;
+ case ID_CONFIG_EXT_LOUDNESS_INFO: {
+ if (cb->cbUniDrc != NULL) {
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
+ cb->cbUniDrcData, hBs, usacConfigExtLength,
+ 1, /* loudnessInfoSet */
+ 0, loudnessInfoSetConfigExtensionPosition, AOT_USAC);
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ return ErrorStatus;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+
+ /* Skip remaining bits. If too many bits were parsed, assume error. */
+ usacConfigExtLength =
+ 8 * usacConfigExtLength - (nbits - FDKgetValidBits(hBs));
+ if (usacConfigExtLength < 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ FDKpushFor(hBs, usacConfigExtLength);
+ }
+
+ return ErrorStatus;
+}
+
+/* This function unifies decoder config parsing of USAC and RSV60:
+ rsv603daDecoderConfig() ISO/IEC DIS 23008-3 Table 8
+ UsacDecoderConfig() ISO/IEC FDIS 23003-3 Table 6
+ */
+static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
+ CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM hBs,
+ const CSTpCallBacks *cb) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ CSUsacConfig *usc = &asc->m_sc.m_usacConfig;
+ int i, numberOfElements;
+ int channelElementIdx =
+ 0; /* index for elements which contain audio channels (sce, cpe, lfe) */
+ SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0};
+
+ numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1;
+ usc->m_usacNumElements = numberOfElements;
+ if (numberOfElements > TP_USAC_MAX_ELEMENTS) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ usc->m_nUsacChannels = 0;
+ usc->m_channelConfigurationIndex = asc->m_channelConfiguration;
+
+ if (asc->m_aot == AOT_USAC) {
+ sc_chan_config = sc_chan_config_tab[usc->m_channelConfigurationIndex];
+
+ if (sc_chan_config.nCh > (SCHAR)TP_USAC_MAX_SPEAKERS) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
- if ( self->m_sbrPresentFlag == 1 ) {
- self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
+ for (i = 0; i < numberOfElements; i++) {
+ MP4_ELEMENT_ID usacElementType = (MP4_ELEMENT_ID)(
+ FDKreadBits(hBs, 2) | USAC_ID_BIT); /* set USAC_ID_BIT to map
+ usacElementType to
+ MP4_ELEMENT_ID enum */
+ usc->element[i].usacElementType = usacElementType;
+
+ /* sanity check: update element counter */
+ if (asc->m_aot == AOT_USAC) {
+ switch (usacElementType) {
+ case ID_USAC_SCE:
+ sc_chan_config.nSCE--;
+ break;
+ case ID_USAC_CPE:
+ sc_chan_config.nCPE--;
+ break;
+ case ID_USAC_LFE:
+ sc_chan_config.nLFE--;
+ break;
+ default:
+ break;
+ }
+ if (usc->m_channelConfigurationIndex) {
+ /* sanity check: no element counter may be smaller zero */
+ if (sc_chan_config.nCPE < 0 || sc_chan_config.nSCE < 0 ||
+ sc_chan_config.nLFE < 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
- if ((INT)self->m_extensionSamplingFrequency <= 0) {
+ switch (usacElementType) {
+ case ID_USAC_SCE:
+ /* UsacCoreConfig() ISO/IEC FDIS 23003-3 Table 10 */
+ if (FDKreadBit(hBs)) { /* tw_mdct */
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1);
+ /* end of UsacCoreConfig() */
+ if (usc->m_sbrRatioIndex > 0) {
+ if (cb->cbSbr == NULL) {
+ return TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ /* SbrConfig() ISO/IEC FDIS 23003-3 Table 11 */
+ usc->element[i].m_harmonicSBR = FDKreadBit(hBs);
+ usc->element[i].m_interTes = FDKreadBit(hBs);
+ usc->element[i].m_pvc = FDKreadBit(hBs);
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, ID_SCE,
+ channelElementIdx, usc->element[i].m_harmonicSBR,
+ usc->element[i].m_stereoConfigIndex, asc->configMode,
+ &asc->SbrConfigChanged, 1)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ /* end of SbrConfig() */
+ }
+ usc->m_nUsacChannels += 1;
+ channelElementIdx++;
+ break;
+
+ case ID_USAC_CPE:
+ /* UsacCoreConfig() ISO/IEC FDIS 23003-3 Table 10 */
+ if (FDKreadBit(hBs)) { /* tw_mdct */
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1);
+ /* end of UsacCoreConfig() */
+ if (usc->m_sbrRatioIndex > 0) {
+ if (cb->cbSbr == NULL) return TRANSPORTDEC_UNKOWN_ERROR;
+ /* SbrConfig() ISO/IEC FDIS 23003-3 */
+ usc->element[i].m_harmonicSBR = FDKreadBit(hBs);
+ usc->element[i].m_interTes = FDKreadBit(hBs);
+ usc->element[i].m_pvc = FDKreadBit(hBs);
+ {
+ INT bitsToSkip = skipSbrHeader(hBs, 1);
+ /* read stereoConfigIndex */
+ usc->element[i].m_stereoConfigIndex = FDKreadBits(hBs, 2);
+ /* rewind */
+ FDKpushBack(hBs, bitsToSkip + 2);
+ }
+ {
+ MP4_ELEMENT_ID el_type =
+ (usc->element[i].m_stereoConfigIndex == 1 ||
+ usc->element[i].m_stereoConfigIndex == 2)
+ ? ID_SCE
+ : ID_CPE;
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, el_type,
+ channelElementIdx, usc->element[i].m_harmonicSBR,
+ usc->element[i].m_stereoConfigIndex, asc->configMode,
+ &asc->SbrConfigChanged, 1)) {
return TRANSPORTDEC_PARSE_ERROR;
}
}
- if ( self->m_extensionAudioObjectType == AOT_ER_BSAC ) {
- self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
- bitsAvailable -= 4;
+ /* end of SbrConfig() */
+
+ usc->element[i].m_stereoConfigIndex =
+ FDKreadBits(hBs, 2); /* Needed in RM5 syntax */
+
+ if (usc->element[i].m_stereoConfigIndex > 0) {
+ if (cb->cbSsc != NULL) {
+ /* Mps212Config() ISO/IEC FDIS 23003-3 */
+ if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot,
+ asc->m_extensionSamplingFrequency,
+ usc->element[i].m_stereoConfigIndex,
+ usc->m_coreSbrFrameLengthIndex,
+ 0, /* don't know the length */
+ asc->configMode, &asc->SacConfigChanged)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ /* end of Mps212Config() */
+ } else {
+ return TRANSPORTDEC_UNKOWN_ERROR;
+ }
}
+ } else {
+ usc->element[i].m_stereoConfigIndex = 0;
}
- /* Update counter because of variable length fields (AOT and sampling rate) */
- bitsAvailable = (INT)FDKgetValidBits(bs);
+ usc->m_nUsacChannels += 2;
+
+ channelElementIdx++;
+ break;
+
+ case ID_USAC_LFE:
+ usc->element[i].m_noiseFilling = 0;
+ usc->m_nUsacChannels += 1;
+ if (usc->m_sbrRatioIndex > 0) {
+ /* Use SBR for upsampling */
+ if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR;
+ usc->element[i].m_harmonicSBR = (UCHAR)0;
+ usc->element[i].m_interTes = (UCHAR)0;
+ usc->element[i].m_pvc = (UCHAR)0;
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, ID_LFE,
+ channelElementIdx, usc->element[i].m_harmonicSBR,
+ usc->element[i].m_stereoConfigIndex, asc->configMode,
+ &asc->SbrConfigChanged, 1)) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ channelElementIdx++;
+ break;
+
+ case ID_USAC_EXT:
+ ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0,
+ asc->m_samplesPerFrame, 0, asc->m_aot);
+
+ if (ErrorStatus) {
+ return ErrorStatus;
+ }
+ break;
+
+ default:
+ /* non USAC-element encountered */
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+
+ if (asc->m_aot == AOT_USAC) {
+ if (usc->m_channelConfigurationIndex) {
+ /* sanity check: all element counter must be zero */
+ if (sc_chan_config.nCPE | sc_chan_config.nSCE | sc_chan_config.nLFE) {
+ return TRANSPORTDEC_PARSE_ERROR;
}
- break;
- case ASCEXT_PS: /* 0x548 */
- if ( (lastAscExt == ASCEXT_SBR)
- && (self->m_extensionAudioObjectType == AOT_SBR)
- && (bitsAvailable > 0) )
- { /* Get PS extension configuration */
- self->m_psPresentFlag = FDKreadBits(bs, 1);
- bitsAvailable -= 1;
+ } else {
+ /* sanity check: number of audio channels shall be equal to or smaller
+ * than the accumulated sum of all channels */
+ if ((INT)(-2 * sc_chan_config.nCPE - sc_chan_config.nSCE -
+ sc_chan_config.nLFE) < (INT)usc->numAudioChannels) {
+ return TRANSPORTDEC_PARSE_ERROR;
}
- break;
- default:
- /* Just ignore anything. */
- return TRANSPORTDEC_OK;
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/* Mapping of coreSbrFrameLengthIndex defined by Table 70 in ISO/IEC 23003-3 */
+static TRANSPORTDEC_ERROR UsacConfig_SetCoreSbrFrameLengthIndex(
+ CSAudioSpecificConfig *asc, int coreSbrFrameLengthIndex) {
+ int sbrRatioIndex_val;
+
+ if (coreSbrFrameLengthIndex > 4) {
+ return TRANSPORTDEC_PARSE_ERROR; /* reserved values */
+ }
+ asc->m_sc.m_usacConfig.m_coreSbrFrameLengthIndex = coreSbrFrameLengthIndex;
+ asc->m_samplesPerFrame = usacFrameLength[coreSbrFrameLengthIndex];
+ sbrRatioIndex_val = sbrRatioIndex[coreSbrFrameLengthIndex];
+ asc->m_sc.m_usacConfig.m_sbrRatioIndex = sbrRatioIndex_val;
+
+ if (sbrRatioIndex_val > 0) {
+ asc->m_sbrPresentFlag = 1;
+ asc->m_extensionSamplingFrequency = asc->m_samplingFrequency;
+ asc->m_extensionSamplingFrequencyIndex = asc->m_samplingFrequencyIndex;
+ switch (sbrRatioIndex_val) {
+ case 1: /* sbrRatio = 4:1 */
+ asc->m_samplingFrequency >>= 2;
+ asc->m_samplesPerFrame >>= 2;
+ break;
+ case 2: /* sbrRatio = 8:3 */
+ asc->m_samplingFrequency = (asc->m_samplingFrequency * 3) / 8;
+ asc->m_samplesPerFrame = (asc->m_samplesPerFrame * 3) / 8;
+ break;
+ case 3: /* sbrRatio = 2:1 */
+ asc->m_samplingFrequency >>= 1;
+ asc->m_samplesPerFrame >>= 1;
+ break;
+ default:
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ asc->m_samplingFrequencyIndex =
+ getSamplingRateIndex(asc->m_samplingFrequency, 4);
+ }
+
+ return TRANSPORTDEC_OK;
+}
+
+static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
+ HANDLE_FDK_BITSTREAM hBs,
+ CSTpCallBacks *cb) {
+ int usacSamplingFrequency, channelConfigurationIndex, coreSbrFrameLengthIndex;
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+
+ /* Start bit position of usacConfig */
+ INT nbits = (INT)FDKgetValidBits(hBs);
+
+ usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5);
+ asc->m_samplingFrequency = (UINT)usacSamplingFrequency;
+
+ coreSbrFrameLengthIndex = FDKreadBits(hBs, 3);
+ if (UsacConfig_SetCoreSbrFrameLengthIndex(asc, coreSbrFrameLengthIndex) !=
+ TRANSPORTDEC_OK) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ channelConfigurationIndex = FDKreadBits(hBs, 5);
+ if (channelConfigurationIndex > 2) {
+ return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2]
+ are supported */
+ }
+
+ if (channelConfigurationIndex == 0) {
+ return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2]
+ are supported */
+ }
+ asc->m_channelConfiguration = channelConfigurationIndex;
+
+ err = UsacRsv60DecoderConfig_Parse(asc, hBs, cb);
+ if (err != TRANSPORTDEC_OK) {
+ return err;
+ }
+
+ if (FDKreadBits(hBs, 1)) { /* usacConfigExtensionPresent */
+ err = configExtension(&asc->m_sc.m_usacConfig, hBs, cb);
+ if (err != TRANSPORTDEC_OK) {
+ return err;
+ }
+ }
+
+ /* sanity check whether number of channels signaled in UsacDecoderConfig()
+ matches the number of channels required by channelConfigurationIndex */
+ if ((channelConfigurationIndex > 0) &&
+ (sc_chan_config_tab[channelConfigurationIndex].nCh !=
+ asc->m_sc.m_usacConfig.m_nUsacChannels)) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ /* Copy UsacConfig() to asc->m_sc.m_usacConfig.UsacConfig[] buffer. */
+ INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits;
+ StoreConfigAsBitstream(hBs, configSize_bits,
+ asc->m_sc.m_usacConfig.UsacConfig,
+ TP_USAC_MAX_CONFIG_LEN);
+ asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits);
+
+ return err;
+}
+
+static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(
+ CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb) {
+ TP_ASC_EXTENSION_ID lastAscExt, ascExtId = ASCEXT_UNKOWN;
+ INT bitsAvailable = (INT)FDKgetValidBits(bs);
+
+ while (bitsAvailable >= 11) {
+ lastAscExt = ascExtId;
+ ascExtId = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11);
+ bitsAvailable -= 11;
+
+ switch (ascExtId) {
+ case ASCEXT_SBR: /* 0x2b7 */
+ if ((self->m_extensionAudioObjectType != AOT_SBR) &&
+ (bitsAvailable >= 5)) {
+ self->m_extensionAudioObjectType = getAOT(bs);
+
+ if ((self->m_extensionAudioObjectType == AOT_SBR) ||
+ (self->m_extensionAudioObjectType ==
+ AOT_ER_BSAC)) { /* Get SBR extension configuration */
+ self->m_sbrPresentFlag = FDKreadBits(bs, 1);
+ if (self->m_aot == AOT_USAC && self->m_sbrPresentFlag > 0 &&
+ self->m_sc.m_usacConfig.m_sbrRatioIndex == 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ if (self->m_sbrPresentFlag == 1) {
+ self->m_extensionSamplingFrequency = getSampleRate(
+ bs, &self->m_extensionSamplingFrequencyIndex, 4);
+
+ if ((INT)self->m_extensionSamplingFrequency <= 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ if (self->m_extensionAudioObjectType == AOT_ER_BSAC) {
+ self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
+ }
+ }
+ /* Update counter because of variable length fields (AOT and sampling
+ * rate) */
+ bitsAvailable = (INT)FDKgetValidBits(bs);
+ }
+ break;
+ case ASCEXT_PS: /* 0x548 */
+ if ((lastAscExt == ASCEXT_SBR) &&
+ (self->m_extensionAudioObjectType == AOT_SBR) &&
+ (bitsAvailable > 0)) { /* Get PS extension configuration */
+ self->m_psPresentFlag = FDKreadBits(bs, 1);
+ bitsAvailable -= 1;
+ }
+ break;
+ case ASCEXT_MPS: /* 0x76a */
+ if (self->m_extensionAudioObjectType == AOT_MPEGS) break;
+ case ASCEXT_LDMPS: /* 0x7cc */
+ if ((ascExtId == ASCEXT_LDMPS) &&
+ (self->m_extensionAudioObjectType == AOT_LD_MPEGS))
+ break;
+ if (bitsAvailable >= 1) {
+ bitsAvailable -= 1;
+ if (FDKreadBits(bs, 1)) { /* self->m_mpsPresentFlag */
+ int sscLen = FDKreadBits(bs, 8);
+ bitsAvailable -= 8;
+ if (sscLen == 0xFF) {
+ sscLen += FDKreadBits(bs, 16);
+ bitsAvailable -= 16;
+ }
+ FDKpushFor(bs, sscLen); /* Skip SSC to be able to read the next
+ extension if there is one. */
+
+ bitsAvailable -= sscLen * 8;
+ }
+ }
+ break;
+ case ASCEXT_SAOC:
+ if ((ascExtId == ASCEXT_SAOC) &&
+ (self->m_extensionAudioObjectType == AOT_SAOC))
+ break;
+ if (FDKreadBits(bs, 1)) { /* saocPresent */
+ int saocscLen = FDKreadBits(bs, 8);
+ bitsAvailable -= 8;
+ if (saocscLen == 0xFF) {
+ saocscLen += FDKreadBits(bs, 16);
+ bitsAvailable -= 16;
+ }
+ FDKpushFor(bs, saocscLen);
+ bitsAvailable -= saocscLen * 8;
+ }
+ break;
+ default:
+ /* Just ignore anything. */
+ return TRANSPORTDEC_OK;
}
}
@@ -1237,134 +2070,149 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(CSAudioSpecificConfig *sel
* API Functions
*/
-void AudioSpecificConfig_Init(CSAudioSpecificConfig *asc)
-{
+void AudioSpecificConfig_Init(CSAudioSpecificConfig *asc) {
FDKmemclear(asc, sizeof(CSAudioSpecificConfig));
/* Init all values that should not be zero. */
- asc->m_aot = AOT_NONE;
+ asc->m_aot = AOT_NONE;
asc->m_samplingFrequencyIndex = 0xf;
- asc->m_epConfig = -1;
- asc->m_extensionAudioObjectType = AOT_NULL_OBJECT;
-#ifdef TP_PCE_ENABLE
+ asc->m_epConfig = -1;
+ asc->m_extensionAudioObjectType = AOT_NULL_OBJECT;
CProgramConfig_Init(&asc->m_progrConfigElement);
-#endif
}
TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
- CSAudioSpecificConfig *self,
- HANDLE_FDK_BITSTREAM bs,
- int fExplicitBackwardCompatible,
- CSTpCallBacks *cb
- )
-{
+ CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs,
+ int fExplicitBackwardCompatible, CSTpCallBacks *cb, UCHAR configMode,
+ UCHAR configChanged, AUDIO_OBJECT_TYPE m_aot) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
UINT ascStartAnchor = FDKgetValidBits(bs);
int frameLengthFlag = -1;
AudioSpecificConfig_Init(self);
- self->m_aot = getAOT(bs);
- self->m_samplingFrequency = getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
- if (self->m_samplingFrequency <= 0) {
- return TRANSPORTDEC_PARSE_ERROR;
- }
+ self->configMode = configMode;
+ self->AacConfigChanged = configChanged;
+ self->SbrConfigChanged = configChanged;
+ self->SacConfigChanged = configChanged;
- self->m_channelConfiguration = FDKreadBits(bs,4);
+ if (m_aot != AOT_NULL_OBJECT) {
+ self->m_aot = m_aot;
+ } else {
+ self->m_aot = getAOT(bs);
+ self->m_samplingFrequency =
+ getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
+ if (self->m_samplingFrequency <= 0) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
- /* SBR extension ( explicit non-backwards compatible mode ) */
- self->m_sbrPresentFlag = 0;
- self->m_psPresentFlag = 0;
+ self->m_channelConfiguration = FDKreadBits(bs, 4);
- if ( self->m_aot == AOT_SBR || self->m_aot == AOT_PS ) {
- self->m_extensionAudioObjectType = AOT_SBR;
+ /* SBR extension ( explicit non-backwards compatible mode ) */
+ self->m_sbrPresentFlag = 0;
+ self->m_psPresentFlag = 0;
- self->m_sbrPresentFlag = 1;
- if ( self->m_aot == AOT_PS ) {
- self->m_psPresentFlag = 1;
- }
+ if (self->m_aot == AOT_SBR || self->m_aot == AOT_PS) {
+ self->m_extensionAudioObjectType = AOT_SBR;
- self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
- self->m_aot = getAOT(bs);
+ self->m_sbrPresentFlag = 1;
+ if (self->m_aot == AOT_PS) {
+ self->m_psPresentFlag = 1;
+ }
- } else {
- self->m_extensionAudioObjectType = AOT_NULL_OBJECT;
+ self->m_extensionSamplingFrequency =
+ getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
+ self->m_aot = getAOT(bs);
+
+ switch (self->m_aot) {
+ case AOT_AAC_LC:
+ break;
+ case AOT_ER_BSAC:
+ break;
+ default:
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+
+ if (self->m_aot == AOT_ER_BSAC) {
+ self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
+ }
+ } else {
+ self->m_extensionAudioObjectType = AOT_NULL_OBJECT;
+ }
}
/* Parse whatever specific configs */
- switch (self->m_aot)
- {
-#ifdef TP_GA_ENABLE
+ switch (self->m_aot) {
case AOT_AAC_LC:
+ case AOT_AAC_SCAL:
case AOT_ER_AAC_LC:
case AOT_ER_AAC_LD:
case AOT_ER_AAC_SCAL:
case AOT_ER_BSAC:
- if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig, self, bs, ascStartAnchor)) != TRANSPORTDEC_OK ) {
+ if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig,
+ self, bs, ascStartAnchor)) !=
+ TRANSPORTDEC_OK) {
return (ErrorStatus);
}
frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag;
break;
-#endif /* TP_GA_ENABLE */
case AOT_MPEGS:
if (cb->cbSsc != NULL) {
- cb->cbSsc(
- cb->cbSscData,
- bs,
- self->m_aot,
- self->m_samplingFrequency,
- 1,
- 0 /* don't know the length */
- );
+ if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency,
+ 1, -1, /* nTimeSlots: read from bitstream */
+ 0, /* don't know the length */
+ self->configMode, &self->SacConfigChanged)) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
} else {
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
break;
-#ifdef TP_ELD_ENABLE
case AOT_ER_AAC_ELD:
- if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK ) {
+ if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) !=
+ TRANSPORTDEC_OK) {
return (ErrorStatus);
}
frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag;
self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag;
- self->m_extensionSamplingFrequency = (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate+1) * self->m_samplingFrequency;
+ self->m_extensionSamplingFrequency =
+ (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate + 1) *
+ self->m_samplingFrequency;
+ break;
+ case AOT_USAC:
+ if ((ErrorStatus = UsacConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK) {
+ return (ErrorStatus);
+ }
break;
-#endif /* TP_ELD_ENABLE */
default:
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
- break;
}
/* Frame length */
- switch (self->m_aot)
- {
-#if defined(TP_GA_ENABLE) || defined(TP_USAC_ENABLE)
+ switch (self->m_aot) {
case AOT_AAC_LC:
+ case AOT_AAC_SCAL:
case AOT_ER_AAC_LC:
case AOT_ER_AAC_SCAL:
case AOT_ER_BSAC:
- /*case AOT_USAC:*/
+ /*case AOT_USAC:*/
if (!frameLengthFlag)
self->m_samplesPerFrame = 1024;
else
self->m_samplesPerFrame = 960;
break;
-#endif /* TP_GA_ENABLE */
-#if defined(TP_GA_ENABLE)
case AOT_ER_AAC_LD:
if (!frameLengthFlag)
self->m_samplesPerFrame = 512;
else
self->m_samplesPerFrame = 480;
break;
-#endif /* defined(TP_GA_ENABLE) */
default:
break;
}
- switch (self->m_aot)
- {
+ switch (self->m_aot) {
case AOT_ER_AAC_LC:
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
@@ -1372,40 +2220,196 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
case AOT_ER_CELP:
case AOT_ER_HVXC:
case AOT_ER_BSAC:
- self->m_epConfig = FDKreadBits(bs,2);
+ self->m_epConfig = FDKreadBits(bs, 2);
if (self->m_epConfig > 1) {
- return TRANSPORTDEC_UNSUPPORTED_FORMAT; // EPCONFIG;
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; // EPCONFIG;
}
break;
default:
break;
}
- if (fExplicitBackwardCompatible) {
+ if (fExplicitBackwardCompatible &&
+ (self->m_aot == AOT_AAC_LC || self->m_aot == AOT_ER_AAC_LD ||
+ self->m_aot == AOT_ER_BSAC)) {
ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb);
}
+ /* Copy config() to asc->config[] buffer. */
+ if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) {
+ INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor;
+ StoreConfigAsBitstream(bs, configSize_bits, self->config,
+ TP_USAC_MAX_CONFIG_LEN);
+ self->configBits = fAbs(configSize_bits);
+ }
+
return (ErrorStatus);
}
+static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig(
+ CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM hBs, int audioMode,
+ CSTpCallBacks *cb /* use cb == NULL to signal config check only mode */
+) {
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ CSUsacConfig *usc = &asc->m_sc.m_usacConfig;
+ int elemIdx = 0;
+
+ usc->element[elemIdx].m_stereoConfigIndex = 0;
+
+ usc->m_usacNumElements = 1; /* Currently all extension elements are skipped
+ -> only one SCE or CPE. */
+
+ switch (audioMode) {
+ case 0: /* mono: ID_USAC_SCE */
+ usc->element[elemIdx].usacElementType = ID_USAC_SCE;
+ usc->m_nUsacChannels = 1;
+ usc->element[elemIdx].m_noiseFilling = FDKreadBits(hBs, 1);
+ if (usc->m_sbrRatioIndex > 0) {
+ if (cb == NULL) {
+ return ErrorStatus;
+ }
+ if (cb->cbSbr != NULL) {
+ usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs);
+ usc->element[elemIdx].m_interTes = FDKreadBit(hBs);
+ usc->element[elemIdx].m_pvc = FDKreadBit(hBs);
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, ID_SCE, elemIdx,
+ usc->element[elemIdx].m_harmonicSBR,
+ usc->element[elemIdx].m_stereoConfigIndex,
+ asc->configMode, &asc->SbrConfigChanged, 1)) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+ break;
+ case 2: /* stereo: ID_USAC_CPE */
+ usc->element[elemIdx].usacElementType = ID_USAC_CPE;
+ usc->m_nUsacChannels = 2;
+ usc->element[elemIdx].m_noiseFilling = FDKreadBits(hBs, 1);
+ if (usc->m_sbrRatioIndex > 0) {
+ usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs);
+ usc->element[elemIdx].m_interTes = FDKreadBit(hBs);
+ usc->element[elemIdx].m_pvc = FDKreadBit(hBs);
+ {
+ INT bitsToSkip = skipSbrHeader(hBs, 1);
+ /* read stereoConfigIndex */
+ usc->element[elemIdx].m_stereoConfigIndex = FDKreadBits(hBs, 2);
+ /* rewind */
+ FDKpushBack(hBs, bitsToSkip + 2);
+ }
+ /*
+ The application of the following tools is mutually exclusive per audio
+ stream configuration (see clause 5.3.2, xHE-AAC codec configuration):
+ - MPS212 parametric stereo tool with residual coding
+ (stereoConfigIndex>1); and
+ - QMF based Harmonic Transposer (harmonicSBR==1).
+ */
+ if ((usc->element[elemIdx].m_stereoConfigIndex > 1) &&
+ usc->element[elemIdx].m_harmonicSBR) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ /*
+ The 4:1 sbrRatio (sbrRatioIndex==1 in [11]) may only be employed:
+ - in mono operation; or
+ - in stereo operation if parametric stereo (MPS212) without residual
+ coding is applied, i.e. if stereoConfigIndex==1 (see clause 5.3.2,
+ xHE-AAC codec configuration).
+ */
+ if ((usc->m_sbrRatioIndex == 1) &&
+ (usc->element[elemIdx].m_stereoConfigIndex != 1)) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ if (cb == NULL) {
+ return ErrorStatus;
+ }
+ {
+ MP4_ELEMENT_ID el_type =
+ (usc->element[elemIdx].m_stereoConfigIndex == 1 ||
+ usc->element[elemIdx].m_stereoConfigIndex == 2)
+ ? ID_SCE
+ : ID_CPE;
+ if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR;
+ if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
+ asc->m_extensionSamplingFrequency,
+ asc->m_samplesPerFrame, asc->m_aot, el_type, elemIdx,
+ usc->element[elemIdx].m_harmonicSBR,
+ usc->element[elemIdx].m_stereoConfigIndex,
+ asc->configMode, &asc->SbrConfigChanged, 1)) {
+ return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ /*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2);
+ if (usc->element[elemIdx].m_stereoConfigIndex > 0) {
+ if (cb->cbSsc != NULL) {
+ ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
+ cb->cbSscData, hBs,
+ AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */
+ asc->m_extensionSamplingFrequency,
+ usc->element[elemIdx].m_stereoConfigIndex,
+ usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */
+ asc->configMode, &asc->SacConfigChanged);
+ } else {
+ /* ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; */
+ }
+ }
+ }
+ break;
+ default:
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ return ErrorStatus;
+}
+
+TRANSPORTDEC_ERROR Drm_xHEAACStaticConfig(
+ CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM bs, int audioMode,
+ CSTpCallBacks *cb /* use cb == NULL to signal config check only mode */
+) {
+ int coreSbrFrameLengthIndexDrm = FDKreadBits(bs, 2);
+ if (UsacConfig_SetCoreSbrFrameLengthIndex(
+ asc, coreSbrFrameLengthIndexDrm + 1) != TRANSPORTDEC_OK) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ asc->m_channelConfiguration = (audioMode) ? 2 : 1;
+
+ if (Drm_xHEAACDecoderConfig(asc, bs, audioMode, cb) != TRANSPORTDEC_OK) {
+ return TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ return TRANSPORTDEC_OK;
+}
+
+/* Mapping of DRM audio sampling rate field to MPEG usacSamplingFrequencyIndex
+ */
+const UCHAR mapSr2MPEGIdx[8] = {
+ 0x1b, /* 9.6 kHz */
+ 0x09, /* 12.0 kHz */
+ 0x08, /* 16.0 kHz */
+ 0x17, /* 19.2 kHz */
+ 0x06, /* 24.0 kHz */
+ 0x05, /* 32.0 kHz */
+ 0x12, /* 38.4 kHz */
+ 0x03 /* 48.0 kHz */
+};
+
TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
- CSAudioSpecificConfig *self,
- HANDLE_FDK_BITSTREAM bs
- )
-{
+ CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs,
+ CSTpCallBacks *cb, /* use cb == NULL to signal config check only mode */
+ UCHAR configMode, UCHAR configChanged) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
AudioSpecificConfig_Init(self);
- if ((INT)FDKgetValidBits(bs) < 20) {
+ if ((INT)FDKgetValidBits(bs) < 16) {
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
goto bail;
- }
- else {
+ } else {
/* DRM - Audio information data entity - type 9
- - Short Id 2 bits
- - Stream Id 2 bits
+ - Short Id 2 bits (not part of the config buffer)
+ - Stream Id 2 bits (not part of the config buffer)
- audio coding 2 bits
- SBR flag 1 bit
- audio mode 2 bits
@@ -1417,54 +2421,64 @@ TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
int audioCoding, audioMode, cSamplingFreq, coderField, sfIdx, sbrFlag;
- /* Read the SDC field */
- FDKreadBits(bs,4); /* Short and Stream Id */
+ self->configMode = configMode;
+ self->AacConfigChanged = configChanged;
+ self->SbrConfigChanged = configChanged;
+ self->SacConfigChanged = configChanged;
- audioCoding = FDKreadBits(bs, 2);
- sbrFlag = FDKreadBits(bs, 1);
- audioMode = FDKreadBits(bs, 2);
- cSamplingFreq = FDKreadBits(bs, 3); /* audio sampling rate */
+ /* Read the SDC field */
+ audioCoding = FDKreadBits(bs, 2);
+ sbrFlag = FDKreadBits(bs, 1);
+ audioMode = FDKreadBits(bs, 2);
+ cSamplingFreq = FDKreadBits(bs, 3); /* audio sampling rate */
- FDKreadBits(bs, 2); /* Text and enhancement flag */
- coderField = FDKreadBits(bs, 5);
- FDKreadBits(bs, 1); /* rfa */
+ FDKreadBits(bs, 2); /* Text and enhancement flag */
+ coderField = FDKreadBits(bs, 5);
+ FDKreadBits(bs, 1); /* rfa */
/* Evaluate configuration and fill the ASC */
- switch (cSamplingFreq) {
- case 0: /* 8 kHz */
- sfIdx = 11;
- break;
- case 1: /* 12 kHz */
- sfIdx = 9;
- break;
- case 2: /* 16 kHz */
- sfIdx = 8;
- break;
- case 3: /* 24 kHz */
- sfIdx = 6;
- break;
- case 5: /* 48 kHz */
- sfIdx = 3;
- break;
- case 4: /* reserved */
- case 6: /* reserved */
- case 7: /* reserved */
- default:
- ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
- goto bail;
+ if (audioCoding == 3) {
+ sfIdx = (int)mapSr2MPEGIdx[cSamplingFreq];
+ sbrFlag = 0; /* rfa */
+ } else {
+ switch (cSamplingFreq) {
+ case 0: /* 8 kHz */
+ sfIdx = 11;
+ break;
+ case 1: /* 12 kHz */
+ sfIdx = 9;
+ break;
+ case 2: /* 16 kHz */
+ sfIdx = 8;
+ break;
+ case 3: /* 24 kHz */
+ sfIdx = 6;
+ break;
+ case 5: /* 48 kHz */
+ sfIdx = 3;
+ break;
+ case 4: /* reserved */
+ case 6: /* reserved */
+ case 7: /* reserved */
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
}
self->m_samplingFrequencyIndex = sfIdx;
self->m_samplingFrequency = SamplingRateTable[sfIdx];
- if ( sbrFlag ) {
+ if (sbrFlag) {
UINT i;
int tmp = -1;
self->m_sbrPresentFlag = 1;
self->m_extensionAudioObjectType = AOT_SBR;
self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1;
- for (i=0; i<(sizeof(SamplingRateTable)/sizeof(SamplingRateTable[0])); i++){
- if (SamplingRateTable[i] == self->m_extensionSamplingFrequency){
+ for (i = 0;
+ i < (sizeof(SamplingRateTable) / sizeof(SamplingRateTable[0]));
+ i++) {
+ if (SamplingRateTable[i] == self->m_extensionSamplingFrequency) {
tmp = i;
break;
}
@@ -1474,20 +2488,23 @@ TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
switch (audioCoding) {
case 0: /* AAC */
- self->m_aot = AOT_DRM_AAC ; /* Set pseudo AOT for Drm AAC */
-
+ if (coderField >> 2) {
+ self->m_aot = AOT_DRM_SURROUND; /* Set pseudo AOT for Drm Surround */
+ } else {
+ self->m_aot = AOT_DRM_AAC; /* Set pseudo AOT for Drm AAC */
+ }
switch (audioMode) {
- case 1: /* parametric stereo */
- self->m_psPresentFlag = 1;
- case 0: /* mono */
- self->m_channelConfiguration = 1;
- break;
- case 2: /* stereo */
- self->m_channelConfiguration = 2;
- break;
- default:
- ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
- goto bail;
+ case 1: /* parametric stereo */
+ self->m_psPresentFlag = 1;
+ case 0: /* mono */
+ self->m_channelConfiguration = 1;
+ break;
+ case 2: /* stereo */
+ self->m_channelConfiguration = 2;
+ break;
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
}
self->m_vcb11Flag = 1;
self->m_hcrFlag = 1;
@@ -1502,7 +2519,22 @@ TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
self->m_aot = AOT_ER_HVXC;
self->m_channelConfiguration = 1;
break;
- case 3: /* reserved */
+ case 3: /* xHE-AAC */
+ {
+ /* payload is MPEG conform -> no pseudo DRM AOT needed */
+ self->m_aot = AOT_USAC;
+ }
+ switch (audioMode) {
+ case 0: /* mono */
+ case 2: /* stereo */
+ /* codec specific config 8n bits */
+ ErrorStatus = Drm_xHEAACStaticConfig(self, bs, audioMode, cb);
+ break;
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ break;
default:
ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
self->m_aot = AOT_NONE;
@@ -1518,4 +2550,3 @@ TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
bail:
return (ErrorStatus);
}
-
diff --git a/libMpegTPDec/src/tpdec_drm.cpp b/libMpegTPDec/src/tpdec_drm.cpp
index df319e5..27c1c1d 100644
--- a/libMpegTPDec/src/tpdec_drm.cpp
+++ b/libMpegTPDec/src/tpdec_drm.cpp
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,23 +90,21 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Christian Griebel
+
Description: DRM transport stuff
-******************************************************************************/
+*******************************************************************************/
#include "tpdec_drm.h"
-
#include "FDK_bitstream.h"
-
-
-void drmRead_CrcInit(HANDLE_DRM pDrm) /*!< pointer to drm crc info stucture */
+void drmRead_CrcInit(HANDLE_DRM pDrm) /*!< pointer to drm crc info stucture */
{
FDK_ASSERT(pDrm != NULL);
@@ -103,44 +112,37 @@ void drmRead_CrcInit(HANDLE_DRM pDrm) /*!< pointer to drm crc info stucture
}
int drmRead_CrcStartReg(
- HANDLE_DRM pDrm, /*!< pointer to drm stucture */
- HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
- int mBits /*!< number of bits in crc region */
- )
-{
+ HANDLE_DRM pDrm, /*!< pointer to drm stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+) {
FDK_ASSERT(pDrm != NULL);
FDKcrcReset(&pDrm->crcInfo);
pDrm->crcReadValue = FDKreadBits(hBs, 8);
- return ( FDKcrcStartReg(&pDrm->crcInfo, hBs, mBits) );
-
+ return (FDKcrcStartReg(&pDrm->crcInfo, hBs, mBits));
}
void drmRead_CrcEndReg(
- HANDLE_DRM pDrm, /*!< pointer to drm crc info stucture */
- HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
- int reg /*!< crc region */
- )
-{
+ HANDLE_DRM pDrm, /*!< pointer to drm crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+) {
FDK_ASSERT(pDrm != NULL);
FDKcrcEndReg(&pDrm->crcInfo, hBs, reg);
}
-TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm )
-{
+TRANSPORTDEC_ERROR drmRead_CrcCheck(HANDLE_DRM pDrm) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
USHORT crc;
crc = FDKcrcGetCRC(&pDrm->crcInfo) ^ 0xFF;
- if (crc != pDrm->crcReadValue)
- {
+ if (crc != pDrm->crcReadValue) {
return (TRANSPORTDEC_CRC_ERROR);
}
return (ErrorStatus);
}
-
-
diff --git a/libMpegTPDec/src/tpdec_drm.h b/libMpegTPDec/src/tpdec_drm.h
index 2161b4c..09822dc 100644
--- a/libMpegTPDec/src/tpdec_drm.h
+++ b/libMpegTPDec/src/tpdec_drm.h
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,27 +90,26 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Josef Hoepfl
+
Description: DRM interface
-******************************************************************************/
+*******************************************************************************/
#ifndef TPDEC_DRM_H
#define TPDEC_DRM_H
#include "tpdec_lib.h"
-
#include "FDK_crc.h"
typedef struct {
-
- FDK_CRCINFO crcInfo; /* CRC state info */
- USHORT crcReadValue; /* CRC value read from bitstream data */
+ FDK_CRCINFO crcInfo; /* CRC state info */
+ USHORT crcReadValue; /* CRC value read from bitstream data */
} STRUCT_DRM;
@@ -112,15 +122,14 @@ typedef STRUCT_DRM *HANDLE_DRM;
\return none
*/
-void drmRead_CrcInit( HANDLE_DRM pDrm );
+void drmRead_CrcInit(HANDLE_DRM pDrm);
/**
* \brief Starts CRC region with a maximum number of bits
- * If mBits is positive zero padding will be used for CRC calculation, if there
- * are less than mBits bits available.
- * If mBits is negative no zero padding is done.
- * If mBits is zero the memory for the buffer is allocated dynamically, the
- * number of bits is not limited.
+ * If mBits is positive zero padding will be used for CRC calculation, if
+ * there are less than mBits bits available. If mBits is negative no zero
+ * padding is done. If mBits is zero the memory for the buffer is
+ * allocated dynamically, the number of bits is not limited.
*
* \param pDrm DRM data handle
* \param hBs bitstream handle, on which the CRC region referes to
@@ -128,11 +137,7 @@ void drmRead_CrcInit( HANDLE_DRM pDrm );
*
* \return ID for the created region, -1 in case of an error
*/
-int drmRead_CrcStartReg(
- HANDLE_DRM pDrm,
- HANDLE_FDK_BITSTREAM hBs,
- int mBits
- );
+int drmRead_CrcStartReg(HANDLE_DRM pDrm, HANDLE_FDK_BITSTREAM hBs, int mBits);
/**
* \brief Ends CRC region identified by reg
@@ -143,52 +148,55 @@ int drmRead_CrcStartReg(
*
* \return none
*/
-void drmRead_CrcEndReg(
- HANDLE_DRM pDrm,
- HANDLE_FDK_BITSTREAM hBs,
- int reg
- );
+void drmRead_CrcEndReg(HANDLE_DRM pDrm, HANDLE_FDK_BITSTREAM hBs, int reg);
/**
* \brief Check CRC
*
- * Checks if the currently calculated CRC matches the CRC field read from the bitstream
- * Deletes all CRC regions.
+ * Checks if the currently calculated CRC matches the CRC field read from the
+ * bitstream Deletes all CRC regions.
*
* \param pDrm DRM data handle
*
* \return Returns 0 if they are identical otherwise 1
*/
-TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm );
+TRANSPORTDEC_ERROR drmRead_CrcCheck(HANDLE_DRM pDrm);
/**
* \brief Check if we have a valid DRM frame at the current bitbuffer position
*
* This function assumes enough bits in buffer for the current frame.
* It reads out the header bits to prepare the bitbuffer for the decode loop.
- * In case the header bits show an invalid bitstream/frame, the whole frame is skipped.
+ * In case the header bits show an invalid bitstream/frame, the whole frame is
+ * skipped.
*
* \param pDrm DRM data handle which is filled with parsed DRM header data
* \param bs handle of bitstream from whom the DRM header is read
*
* \return error status
*/
-TRANSPORTDEC_ERROR drmRead_DecodeHeader(
- HANDLE_DRM pDrm,
- HANDLE_FDK_BITSTREAM bs
- );
+TRANSPORTDEC_ERROR drmRead_DecodeHeader(HANDLE_DRM pDrm,
+ HANDLE_FDK_BITSTREAM bs);
/**
* \brief Parse a Drm specific SDC audio config from a given bitstream handle.
*
- * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct.
+ * \param pAsc A pointer to an allocated
+ * CSAudioSpecificConfig struct.
* \param hBs Bitstream handle.
+ * \param cb A pointer to structure holding callback
+ * information Note: A NULL pointer for cb can be used to signal a "Check Config
+ * only functionality"
+ * \param configMode Config modes: memory allocation mode or
+ * config change detection mode
+ * \param configChanged Indicates a config change
*
* \return Total element count including all SCE, CPE and LFE.
*/
-TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse( CSAudioSpecificConfig *pAsc,
- HANDLE_FDK_BITSTREAM hBs );
-
-
+TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(CSAudioSpecificConfig *pAsc,
+ HANDLE_FDK_BITSTREAM hBs,
+ CSTpCallBacks *cb,
+ const UCHAR configMode,
+ const UCHAR configChanged);
#endif /* TPDEC_DRM_H */
diff --git a/libMpegTPDec/src/tpdec_latm.cpp b/libMpegTPDec/src/tpdec_latm.cpp
index 5710d77..b4f7372 100644
--- a/libMpegTPDec/src/tpdec_latm.cpp
+++ b/libMpegTPDec/src/tpdec_latm.cpp
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,91 +90,151 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Daniel Homm
+
Description:
-******************************************************************************/
+*******************************************************************************/
#include "tpdec_latm.h"
-
#include "FDK_bitstream.h"
+#define TPDEC_TRACKINDEX(p, l) (1 * (p) + (l))
-#define TPDEC_TRACKINDEX(p,l) (2*(p) + (l))
-
-static
-UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs)
-{
+static UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) {
UCHAR bytesForValue = 0, tmp = 0;
int value = 0;
- bytesForValue = (UCHAR) FDKreadBits(bs,2);
+ bytesForValue = (UCHAR)FDKreadBits(bs, 2);
- for (UINT i=0; i<=bytesForValue; i++) {
+ for (UINT i = 0; i <= bytesForValue; i++) {
value <<= 8;
- tmp = (UCHAR) FDKreadBits(bs,8);
+ tmp = (UCHAR)FDKreadBits(bs, 8);
value += tmp;
}
return value;
}
-
-static
-TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement(
- HANDLE_FDK_BITSTREAM bs,
- CLatmDemux *pLatmDemux,
- int m_muxConfigPresent,
- CSTpCallBacks *pTpDecCallbacks,
- CSAudioSpecificConfig *pAsc,
- int *pfConfigFound
- )
-{
+static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement(
+ HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, int m_muxConfigPresent,
+ CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ UCHAR applyAsc = pLatmDemux->applyAsc;
if (m_muxConfigPresent) {
- pLatmDemux->m_useSameStreamMux = FDKreadBits(bs,1);
+ pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1);
if (!pLatmDemux->m_useSameStreamMux) {
- if ((ErrorStatus = CLatmDemux_ReadStreamMuxConfig(bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound))) {
- return (ErrorStatus);
+ int i;
+ UCHAR configChanged = 0;
+ UCHAR configMode = 0;
+
+ FDK_BITSTREAM bsAnchor;
+
+ FDK_BITSTREAM bsAnchorDummyParse;
+
+ if (!pLatmDemux->applyAsc) {
+ bsAnchorDummyParse = *bs;
+ pLatmDemux->newCfgHasAudioPreRoll = 0;
+ /* do dummy-parsing of ASC to determine if there is an audioPreRoll */
+ configMode |= AC_CM_DET_CFG_CHANGE;
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
+ bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
+ configMode, configChanged))) {
+ goto bail;
+ }
+
+ if (pLatmDemux->newCfgHasAudioPreRoll) {
+ pLatmDemux->newCfgHasAudioPreRoll = 0;
+ /* with audioPreRoll we must flush before applying new cfg */
+ pLatmDemux->applyAsc = 0;
+ } else {
+ *bs = bsAnchorDummyParse;
+ pLatmDemux->applyAsc = 1; /* apply new config immediate */
+ }
+ }
+
+ if (pLatmDemux->applyAsc) {
+ for (i = 0; i < 2; i++) {
+ configMode = 0;
+
+ if (i == 0) {
+ configMode |= AC_CM_DET_CFG_CHANGE;
+ bsAnchor = *bs;
+ } else {
+ configMode |= AC_CM_ALLOC_MEM;
+ *bs = bsAnchor;
+ }
+
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = CLatmDemux_ReadStreamMuxConfig(
+ bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound,
+ configMode, configChanged))) {
+ goto bail;
+ }
+
+ if (ErrorStatus == TRANSPORTDEC_OK) {
+ if ((i == 0) && (pAsc->AacConfigChanged || pAsc->SbrConfigChanged ||
+ pAsc->SacConfigChanged)) {
+ int errC;
+
+ configChanged = 1;
+ errC = pTpDecCallbacks->cbFreeMem(pTpDecCallbacks->cbFreeMemData,
+ pAsc);
+ if (errC != 0) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+ }
+ }
}
}
}
- /* If there was no configuration read, its not possible to parse PayloadLengthInfo below. */
- if (! *pfConfigFound) {
- return TRANSPORTDEC_SYNC_ERROR;
+ /* If there was no configuration read, its not possible to parse
+ * PayloadLengthInfo below. */
+ if (!*pfConfigFound) {
+ ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
+ goto bail;
}
if (pLatmDemux->m_AudioMuxVersionA == 0) {
/* Do only once per call, because parsing and decoding is done in-line. */
- if ((ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs,pLatmDemux))) {
- return (ErrorStatus);
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs, pLatmDemux))) {
+ *pfConfigFound = 0;
+ goto bail;
}
} else {
/* audioMuxVersionA > 0 is reserved for future extensions */
ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ *pfConfigFound = 0;
+ goto bail;
+ }
+
+bail:
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ pLatmDemux->applyAsc = applyAsc;
}
return (ErrorStatus);
}
-TRANSPORTDEC_ERROR CLatmDemux_Read(
- HANDLE_FDK_BITSTREAM bs,
- CLatmDemux *pLatmDemux,
- TRANSPORT_TYPE tt,
- CSTpCallBacks *pTpDecCallbacks,
- CSAudioSpecificConfig *pAsc,
- int *pfConfigFound,
- const INT ignoreBufferFullness
- )
-{
+TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,
+ CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt,
+ CSTpCallBacks *pTpDecCallbacks,
+ CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound,
+ const INT ignoreBufferFullness) {
UINT cntBits;
UINT cmpBufferFullness;
UINT audioMuxLengthBytesLast = 0;
@@ -175,29 +246,27 @@ TRANSPORTDEC_ERROR CLatmDemux_Read(
return TRANSPORTDEC_NOT_ENOUGH_BITS;
}
- if ((ErrorStatus = CLatmDemux_ReadAudioMuxElement(bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0), pTpDecCallbacks, pAsc, pfConfigFound)))
+ if (TRANSPORTDEC_OK != (ErrorStatus = CLatmDemux_ReadAudioMuxElement(
+ bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0),
+ pTpDecCallbacks, pAsc, pfConfigFound)))
return (ErrorStatus);
- if (!ignoreBufferFullness)
- {
- cmpBufferFullness = 24+audioMuxLengthBytesLast*8
- + pLatmDemux->m_linfo[0][0].m_bufferFullness* pAsc[TPDEC_TRACKINDEX(0,0)].m_channelConfiguration*32;
+ if (!ignoreBufferFullness) {
+ cmpBufferFullness =
+ 24 + audioMuxLengthBytesLast * 8 +
+ pLatmDemux->m_linfo[0][0].m_bufferFullness *
+ pAsc[TPDEC_TRACKINDEX(0, 0)].m_channelConfiguration * 32;
/* evaluate buffer fullness */
- if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF)
- {
- if (!pLatmDemux->BufferFullnessAchieved)
- {
- if (cntBits < cmpBufferFullness)
- {
+ if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) {
+ if (!pLatmDemux->BufferFullnessAchieved) {
+ if (cntBits < cmpBufferFullness) {
/* condition for start of decoding is not fulfilled */
/* the current frame will not be decoded */
return TRANSPORTDEC_NOT_ENOUGH_BITS;
- }
- else
- {
+ } else {
pLatmDemux->BufferFullnessAchieved = 1;
}
}
@@ -207,227 +276,397 @@ TRANSPORTDEC_ERROR CLatmDemux_Read(
return (ErrorStatus);
}
-
TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
- HANDLE_FDK_BITSTREAM bs,
- CLatmDemux *pLatmDemux,
- CSTpCallBacks *pTpDecCallbacks,
- CSAudioSpecificConfig *pAsc,
- int * pfConfigFound
- )
-{
+ HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux,
+ CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound, UCHAR configMode, UCHAR configChanged) {
+ CSAudioSpecificConfig ascDummy; /* the actual config is needed for flushing,
+ after that new config can be parsed */
+ CSAudioSpecificConfig *pAscDummy;
+ pAscDummy = &ascDummy;
+ pLatmDemux->usacExplicitCfgChanged = 0;
LATM_LAYER_INFO *p_linfo = NULL;
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ UCHAR updateConfig[1 * 1] = {0};
- pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs,1);
+ pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs, 1);
if (pLatmDemux->m_AudioMuxVersion == 0) {
pLatmDemux->m_AudioMuxVersionA = 0;
} else {
- pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs,1);
+ pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs, 1);
}
if (pLatmDemux->m_AudioMuxVersionA == 0) {
if (pLatmDemux->m_AudioMuxVersion == 1) {
pLatmDemux->m_taraBufferFullness = CLatmDemux_GetValue(bs);
}
- pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs,1);
- pLatmDemux->m_noSubFrames = FDKreadBits(bs,6) + 1;
- pLatmDemux->m_numProgram = FDKreadBits(bs,4) + 1;
+ pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs, 1);
+ pLatmDemux->m_noSubFrames = FDKreadBits(bs, 6) + 1;
+ pLatmDemux->m_numProgram = FDKreadBits(bs, 4) + 1;
- if (pLatmDemux->m_numProgram > 1) {
- return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ if (pLatmDemux->m_numProgram > LATM_MAX_PROG) {
+ ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ goto bail;
}
int idCnt = 0;
for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
- pLatmDemux->m_numLayer = FDKreadBits(bs,3) + 1;
- if (pLatmDemux->m_numLayer > 2) {
- return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ pLatmDemux->m_numLayer[prog] = FDKreadBits(bs, 3) + 1;
+ if (pLatmDemux->m_numLayer[prog] > LATM_MAX_LAYER) {
+ ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ goto bail;
}
- for (UINT lay = 0; lay < pLatmDemux->m_numLayer; lay++) {
+ for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
+ int useSameConfig;
p_linfo = &pLatmDemux->m_linfo[prog][lay];
p_linfo->m_streamID = idCnt++;
p_linfo->m_frameLengthInBits = 0;
- if( (prog == 0) && (lay == 0) ) {
- pLatmDemux->m_useSameConfig = 0;
+ if ((prog == 0) && (lay == 0)) {
+ useSameConfig = 0;
} else {
- pLatmDemux->m_useSameConfig = FDKreadBits(bs,1);
+ useSameConfig = FDKreadBits(bs, 1);
}
- if (pLatmDemux->m_useSameConfig) {
- if (lay > 1) {
- FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog,lay)], &pAsc[TPDEC_TRACKINDEX(prog,lay-1)], sizeof(CSAudioSpecificConfig));
+ if (useSameConfig) {
+ if (lay > 0) {
+ FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)],
+ &pAsc[TPDEC_TRACKINDEX(prog, lay - 1)],
+ sizeof(CSAudioSpecificConfig));
} else {
- return TRANSPORTDEC_PARSE_ERROR;
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
}
} else {
- if (pLatmDemux->m_AudioMuxVersion == 1)
- {
+ UINT usacConfigLengthPrev = 0;
+ UCHAR usacConfigPrev[TP_USAC_MAX_CONFIG_LEN];
+
+ if (!(pLatmDemux->applyAsc) &&
+ (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_USAC)) {
+ usacConfigLengthPrev =
+ (UINT)(pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfigBits +
+ 7) >>
+ 3; /* store previous USAC config length */
+ if (usacConfigLengthPrev > TP_USAC_MAX_CONFIG_LEN) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ FDKmemclear(usacConfigPrev, TP_USAC_MAX_CONFIG_LEN);
+ FDKmemcpy(
+ usacConfigPrev,
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)].m_sc.m_usacConfig.UsacConfig,
+ usacConfigLengthPrev); /* store previous USAC config */
+ }
+ if (pLatmDemux->m_AudioMuxVersion == 1) {
FDK_BITSTREAM tmpBs;
- UINT ascStartPos, ascLen=0;
-
+ UINT ascLen = 0;
ascLen = CLatmDemux_GetValue(bs);
- ascStartPos = FDKgetValidBits(bs);
+ /* The ascLen could be wrong, so check if validBits<=bufBits*/
+ if (ascLen > FDKgetValidBits(bs)) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ FDKsyncCache(bs);
tmpBs = *bs;
- FDKsyncCache(&tmpBs);
tmpBs.hBitBuf.ValidBits = ascLen;
-
+
/* Read ASC */
- if ((ErrorStatus = AudioSpecificConfig_Parse(&pAsc[TPDEC_TRACKINDEX(prog,lay)], &tmpBs, 1, pTpDecCallbacks))) {
- return (ErrorStatus);
+ if (pLatmDemux->applyAsc) {
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = AudioSpecificConfig_Parse(
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)], &tmpBs, 1,
+ pTpDecCallbacks, configMode, configChanged,
+ AOT_NULL_OBJECT)))
+ goto bail;
+ } else {
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = AudioSpecificConfig_Parse(
+ pAscDummy, &tmpBs, 1, pTpDecCallbacks, configMode,
+ configChanged, AOT_NULL_OBJECT)))
+ goto bail;
}
- *pfConfigFound = 1;
/* The field p_linfo->m_ascLen could be wrong, so check if */
- if ( 0 > (INT)FDKgetValidBits(&tmpBs)) {
- return TRANSPORTDEC_PARSE_ERROR;
+ if (0 > (INT)FDKgetValidBits(&tmpBs)) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
}
FDKpushFor(bs, ascLen); /* position bitstream after ASC */
- }
- else {
+ } else {
/* Read ASC */
- if ((ErrorStatus = AudioSpecificConfig_Parse(&pAsc[TPDEC_TRACKINDEX(prog,lay)], bs, 0, pTpDecCallbacks))) {
- return (ErrorStatus);
+ if (pLatmDemux->applyAsc) {
+ if (TRANSPORTDEC_OK != (ErrorStatus = AudioSpecificConfig_Parse(
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)],
+ bs, 0, pTpDecCallbacks, configMode,
+ configChanged, AOT_NULL_OBJECT)))
+ goto bail;
+ } else {
+ if (TRANSPORTDEC_OK !=
+ (ErrorStatus = AudioSpecificConfig_Parse(
+ pAscDummy, bs, 0, pTpDecCallbacks, configMode,
+ configChanged, AOT_NULL_OBJECT)))
+ goto bail;
}
}
- {
- int cbError;
+ if (!pLatmDemux->applyAsc) {
+ updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 0;
+ } else {
+ updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 1;
+ }
- cbError = pTpDecCallbacks->cbUpdateConfig(pTpDecCallbacks->cbUpdateConfigData, &pAsc[TPDEC_TRACKINDEX(prog,lay)]);
- if (cbError != 0) {
- return TRANSPORTDEC_UNKOWN_ERROR;
+ if (!pLatmDemux->applyAsc) {
+ if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
+ AOT_USAC) { /* flush in case SMC has changed */
+ const UINT usacConfigLength =
+ (UINT)(pAscDummy->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3;
+ if (usacConfigLength > TP_USAC_MAX_CONFIG_LEN) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ if (usacConfigLength != usacConfigLengthPrev) {
+ FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfig,
+ TP_USAC_MAX_CONFIG_LEN);
+ FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfig,
+ &pAscDummy->m_sc.m_usacConfig.UsacConfig,
+ usacConfigLength); /* store new USAC config */
+ pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfigBits =
+ pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
+ pLatmDemux->usacExplicitCfgChanged = 1;
+ } else {
+ if (FDKmemcmp(usacConfigPrev,
+ pAscDummy->m_sc.m_usacConfig.UsacConfig,
+ usacConfigLengthPrev)) {
+ FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfig,
+ TP_USAC_MAX_CONFIG_LEN);
+ FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfig,
+ &pAscDummy->m_sc.m_usacConfig.UsacConfig,
+ usacConfigLength); /* store new USAC config */
+ pAsc[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.UsacConfigBits =
+ pAscDummy->m_sc.m_usacConfig.UsacConfigBits;
+ pLatmDemux->usacExplicitCfgChanged = 1;
+ }
+ }
+
+ if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.m_usacNumElements) {
+ if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)]
+ .m_sc.m_usacConfig.element[0]
+ .extElement.usacExtElementHasAudioPreRoll) {
+ pLatmDemux->newCfgHasAudioPreRoll =
+ 1; /* if dummy parsed cfg has audioPreRoll we first flush
+ before applying new cfg */
+ }
+ }
}
- *pfConfigFound = 1;
}
}
- p_linfo->m_frameLengthType = FDKreadBits(bs,3);
- switch( p_linfo->m_frameLengthType ) {
- case 0:
- p_linfo->m_bufferFullness = FDKreadBits(bs,8);
-
- if (!pLatmDemux->m_allStreamsSameTimeFraming) {
- if ((lay > 0) && (pAsc[TPDEC_TRACKINDEX(prog,lay)].m_aot == AOT_AAC_SCAL || pAsc[TPDEC_TRACKINDEX(prog,lay)].m_aot == AOT_ER_AAC_SCAL)) {
- return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ p_linfo->m_frameLengthType = FDKreadBits(bs, 3);
+ switch (p_linfo->m_frameLengthType) {
+ case 0:
+ p_linfo->m_bufferFullness = FDKreadBits(bs, 8);
+
+ if (!pLatmDemux->m_allStreamsSameTimeFraming) {
+ if ((lay > 0) &&
+ (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_AAC_SCAL ||
+ pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot ==
+ AOT_ER_AAC_SCAL) &&
+ (pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == AOT_CELP ||
+ pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot ==
+ AOT_ER_CELP)) { /* The layer maybe
+ ignored later so
+ read it anyway: */
+ /* coreFrameOffset = */ FDKreadBits(bs, 6);
+ }
}
- }
- break;
- case 1:
- /* frameLength = FDKreadBits(bs,9); */
- case 3:
- case 4:
- case 5:
- /* CELP */
- case 6:
- case 7:
- /* HVXC */
- default:
- return TRANSPORTDEC_PARSE_ERROR; //_LATM_INVALIDFRAMELENGTHTYPE;
-
- } /* switch framelengthtype*/
-
- } /* layer loop */
- } /* prog loop */
-
- pLatmDemux->m_otherDataPresent = FDKreadBits(bs,1);
- pLatmDemux->m_otherDataLength = 0;
+ break;
+ case 1:
+ p_linfo->m_frameLengthInBits = FDKreadBits(bs, 9);
+ break;
+ case 3:
+ case 4:
+ case 5:
+ /* CELP */
+ case 6:
+ case 7:
+ /* HVXC */
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ } /* switch framelengthtype*/
+
+ } /* layer loop */
+ } /* prog loop */
+
+ pLatmDemux->m_otherDataPresent = FDKreadBits(bs, 1);
+ pLatmDemux->m_otherDataLength = 0;
if (pLatmDemux->m_otherDataPresent) {
- int otherDataLenEsc = 0;
- do {
- pLatmDemux->m_otherDataLength <<= 8; // *= 256
- otherDataLenEsc = FDKreadBits(bs,1);
- pLatmDemux->m_otherDataLength += FDKreadBits(bs,8);
- } while (otherDataLenEsc);
+ if (pLatmDemux->m_AudioMuxVersion == 1) {
+ pLatmDemux->m_otherDataLength = CLatmDemux_GetValue(bs);
+ } else {
+ int otherDataLenEsc = 0;
+ do {
+ pLatmDemux->m_otherDataLength <<= 8; // *= 256
+ otherDataLenEsc = FDKreadBits(bs, 1);
+ pLatmDemux->m_otherDataLength += FDKreadBits(bs, 8);
+ } while (otherDataLenEsc);
+ }
+ if (pLatmDemux->m_audioMuxLengthBytes <
+ (pLatmDemux->m_otherDataLength >> 3)) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
}
- pLatmDemux->m_crcCheckPresent = FDKreadBits(bs,1);
- pLatmDemux->m_crcCheckSum = 0;
+ pLatmDemux->m_crcCheckPresent = FDKreadBits(bs, 1);
if (pLatmDemux->m_crcCheckPresent) {
- pLatmDemux->m_crcCheckSum = FDKreadBits(bs,8);
+ FDKreadBits(bs, 8);
}
- }
- else {
+ } else {
/* audioMuxVersionA > 0 is reserved for future extensions */
ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
+
+ /* Configure source decoder: */
+ if (ErrorStatus == TRANSPORTDEC_OK) {
+ UINT prog;
+ for (prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
+ UINT lay;
+ for (lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
+ if (updateConfig[TPDEC_TRACKINDEX(prog, lay)] != 0) {
+ int cbError;
+ cbError = pTpDecCallbacks->cbUpdateConfig(
+ pTpDecCallbacks->cbUpdateConfigData,
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)],
+ pAsc[TPDEC_TRACKINDEX(prog, lay)].configMode,
+ &pAsc[TPDEC_TRACKINDEX(prog, lay)].AacConfigChanged);
+ if (cbError == TRANSPORTDEC_NEED_TO_RESTART) {
+ *pfConfigFound = 0;
+ ErrorStatus = TRANSPORTDEC_NEED_TO_RESTART;
+ goto bail;
+ }
+ if (cbError != 0) {
+ *pfConfigFound = 0;
+ if (lay == 0) {
+ ErrorStatus = TRANSPORTDEC_SYNC_ERROR;
+ goto bail;
+ }
+ } else {
+ *pfConfigFound = 1;
+ }
+ } else {
+ *pfConfigFound = 1;
+ }
+ }
+ }
+ }
+
+bail:
+ if (ErrorStatus != TRANSPORTDEC_OK) {
+ UCHAR applyAsc = pLatmDemux->applyAsc;
+ FDKmemclear(pLatmDemux, sizeof(CLatmDemux)); /* reset structure */
+ pLatmDemux->applyAsc = applyAsc;
+ } else {
+ /* no error and config parsing is finished */
+ if (configMode == AC_CM_ALLOC_MEM) pLatmDemux->applyAsc = 0;
+ }
+
return (ErrorStatus);
}
-TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux)
-{
+TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
+ CLatmDemux *pLatmDemux) {
TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
int totalPayloadBits = 0;
- if( pLatmDemux->m_allStreamsSameTimeFraming == 1 ) {
- for (UINT prog=0; prog<pLatmDemux->m_numProgram; prog++ ) {
- for (UINT lay=0; lay<pLatmDemux->m_numLayer; lay++ ) {
+ if (pLatmDemux->m_allStreamsSameTimeFraming == 1) {
+ FDK_ASSERT(pLatmDemux->m_numProgram <= LATM_MAX_PROG);
+ for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) {
+ FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER);
+ for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) {
LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay];
- switch (p_linfo->m_frameLengthType ) {
- case 0:
- p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs);
- totalPayloadBits += p_linfo->m_frameLengthInBits;
- break;
- case 3:
- case 5:
- case 7:
- default:
- return TRANSPORTDEC_PARSE_ERROR; //AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE;
+ switch (p_linfo->m_frameLengthType) {
+ case 0:
+ p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs);
+ totalPayloadBits += p_linfo->m_frameLengthInBits;
+ break;
+ case 3:
+ case 5:
+ case 7:
+ default:
+ return TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE;
}
}
}
+ } else {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_TIMEFRAMING;
}
- else {
- ErrorStatus = TRANSPORTDEC_PARSE_ERROR; //AAC_DEC_LATM_TIMEFRAMING;
- }
- if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 && totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes*8) {
+ if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 &&
+ totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes * 8) {
return TRANSPORTDEC_PARSE_ERROR;
}
+
return (ErrorStatus);
}
-int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs)
-{
+int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) {
UCHAR endFlag;
int len = 0;
do {
- UCHAR tmp = (UCHAR) FDKreadBits(bs,8);
+ UCHAR tmp = (UCHAR)FDKreadBits(bs, 8);
endFlag = (tmp < 255);
len += tmp;
- } while( endFlag == 0 );
+ } while (endFlag == 0);
- len <<= 3; /* convert from bytes to bits */
+ len <<= 3; /* convert from bytes to bits */
return len;
}
-int CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux)
-{
- return pLatmDemux->m_linfo[0][0].m_frameLengthInBits;
+UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog,
+ const UINT layer) {
+ UINT nFrameLenBits = 0;
+ if (prog < pLatmDemux->m_numProgram) {
+ if (layer < pLatmDemux->m_numLayer[prog]) {
+ nFrameLenBits = pLatmDemux->m_linfo[prog][layer].m_frameLengthInBits;
+ }
+ }
+ return nFrameLenBits;
}
-int CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux)
-{
+UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) {
return pLatmDemux->m_otherDataPresent ? 1 : 0;
}
-int CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux)
-{
+UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) {
return pLatmDemux->m_otherDataLength;
}
-UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux)
-{
+UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) {
return pLatmDemux->m_noSubFrames;
}
+UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT prog) {
+ UINT numLayer = 0;
+ if (prog < pLatmDemux->m_numProgram) {
+ numLayer = pLatmDemux->m_numLayer[prog];
+ }
+ return numLayer;
+}
diff --git a/libMpegTPDec/src/tpdec_latm.h b/libMpegTPDec/src/tpdec_latm.h
index 6dc13e8..6af553d 100644
--- a/libMpegTPDec/src/tpdec_latm.h
+++ b/libMpegTPDec/src/tpdec_latm.h
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,32 +90,32 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
-/***************************** MPEG-4 AAC Decoder **************************
+/******************* MPEG transport format decoder library *********************
Author(s): Daniel Homm
+
Description:
-******************************************************************************/
+*******************************************************************************/
-#ifndef LATM_DEMUX_H
-#define LATM_DEMUX_H
+#ifndef TPDEC_LATM_H
+#define TPDEC_LATM_H
#include "tpdec_lib.h"
-
#include "FDK_bitstream.h"
-#define MIN_LATM_HEADERLENGTH 9
-#define MIN_LOAS_HEADERLENGTH MIN_LATM_HEADERLENGTH + 24 /* both in bits */
- #define MIN_TP_BUF_SIZE_LOAS ( 8194 )
+#define MIN_LATM_HEADERLENGTH 9
+#define MIN_LOAS_HEADERLENGTH MIN_LATM_HEADERLENGTH + 24 /* both in bits */
+#define MIN_TP_BUF_SIZE_LOAS (8194)
enum {
LATM_MAX_PROG = 1,
- LATM_MAX_LAYER = 2,
- LATM_MAX_VAR_CHUNKS=16,
- LATM_MAX_ID=16
+ LATM_MAX_LAYER = 1,
+ LATM_MAX_VAR_CHUNKS = 16,
+ LATM_MAX_ID = 16
};
typedef struct {
@@ -118,7 +129,7 @@ typedef struct {
LATM_LAYER_INFO m_linfo[LATM_MAX_PROG][LATM_MAX_LAYER];
UINT m_taraBufferFullness;
UINT m_otherDataLength;
- UINT m_audioMuxLengthBytes; /* Length of LOAS payload */
+ UINT m_audioMuxLengthBytes; /* Length of LOAS payload */
UCHAR m_useSameStreamMux;
UCHAR m_AudioMuxVersion;
@@ -126,27 +137,28 @@ typedef struct {
UCHAR m_allStreamsSameTimeFraming;
UCHAR m_noSubFrames;
UCHAR m_numProgram;
- UCHAR m_numLayer;
- UCHAR m_useSameConfig;
+ UCHAR m_numLayer[LATM_MAX_PROG];
UCHAR m_otherDataPresent;
UCHAR m_crcCheckPresent;
- UCHAR m_crcCheckSum;
SCHAR BufferFullnessAchieved;
+ UCHAR
+ usacExplicitCfgChanged; /* explicit config in case of USAC and LOAS/LATM
+ must be compared to IPF cfg */
+ UCHAR applyAsc; /* apply ASC immediate without flushing */
+ UCHAR newCfgHasAudioPreRoll; /* the new (dummy parsed) config has an
+ AudioPreRoll */
} CLatmDemux;
int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs);
-TRANSPORTDEC_ERROR CLatmDemux_Read(
- HANDLE_FDK_BITSTREAM bs,
- CLatmDemux *pLatmDemux,
- TRANSPORT_TYPE tt,
- CSTpCallBacks *pTpDecCallbacks,
- CSAudioSpecificConfig *pAsc,
- int *pfConfigFound,
- const INT ignoreBufferFullness
- );
+TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs,
+ CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt,
+ CSTpCallBacks *pTpDecCallbacks,
+ CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound,
+ const INT ignoreBufferFullness);
/**
* \brief Read StreamMuxConfig
@@ -154,23 +166,26 @@ TRANSPORTDEC_ERROR CLatmDemux_Read(
* \param pLatmDemux pointer to CLatmDemux struct of current LATM context
* \param pTpDecCallbacks Call back structure for configuration callbacks
* \param pAsc pointer to a ASC for configuration storage
- * \param pfConfigFound pointer to a flag which is set to 1 if a configuration was found and processed successfully
+ * \param pfConfigFound pointer to a flag which is set to 1 if a configuration
+ * was found and processed successfully
+ * \param configMode Config modes: memory allocation mode or config change
+ * detection mode
+ * \param configChanged Indicates a config change
* \return error code
*/
TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig(
- HANDLE_FDK_BITSTREAM bs,
- CLatmDemux *pLatmDemux,
- CSTpCallBacks *pTpDecCallbacks,
- CSAudioSpecificConfig *pAsc,
- int * pfConfigFound
- );
-
-TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux);
-
-int CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux);
-int CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux);
-int CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux);
-UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux);
+ HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux,
+ CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc,
+ int *pfConfigFound, UCHAR configMode, UCHAR configChanged);
+
+TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs,
+ CLatmDemux *pLatmDemux);
+UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog,
+ const UINT layer);
+UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux);
+UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux);
+UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux);
+UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT program);
-#endif /* LATM_DEMUX_H */
+#endif /* TPDEC_LATM_H */
diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp
index 24f755b..10e3352 100644
--- a/libMpegTPDec/src/tpdec_lib.cpp
+++ b/libMpegTPDec/src/tpdec_lib.cpp
@@ -1,74 +1,85 @@
-
-/* -----------------------------------------------------------------------------------------------------------
+/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
2. COPYRIGHT LICENSE
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
3. NO PATENT LICENSE
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
4. DISCLAIMER
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
5. CONTACT INFORMATION
@@ -79,20 +90,20 @@ Am Wolfsmantel 33
www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
+----------------------------------------------------------------------------- */
+
+/******************* MPEG transport format decoder library *********************
-/************************** MPEG-4 Transport Decoder ************************
+ Author(s): Manuel Jander
- Author(s): Manuel Jander
Description: MPEG Transport decoder
-******************************************************************************/
+*******************************************************************************/
#include "tpdec_lib.h"
/* library version */
-#include "version"
-
+#include "tp_version.h"
#include "tp_data.h"
@@ -104,6 +115,7 @@ amm-info@iis.fraunhofer.de
#include "tpdec_drm.h"
+#include "FDK_crc.h"
#define MODULE_NAME "transportDec"
@@ -118,51 +130,70 @@ typedef union {
} transportdec_parser_t;
-struct TRANSPORTDEC
-{
- TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */
-
- CSTpCallBacks callbacks; /*!< Struct holding callback and its data */
-
- FDK_BITSTREAM bitStream[2]; /* Bitstream reader */
- UCHAR *bsBuffer; /* Internal bitstreamd data buffer (unallocated in case of TT_MP4_RAWPACKETS) */
-
- transportdec_parser_t parser; /* Format specific parser structs. */
-
- CSAudioSpecificConfig asc[(1*2)]; /* Audio specific config from the last config found. */
- UINT globalFramePos; /* Global transport frame reference bit position. */
- UINT accessUnitAnchor[2]; /* Current access unit start bit position. */
- INT auLength[2]; /* Length of current access unit. */
- INT numberOfRawDataBlocks; /* Current number of raw data blocks contained remaining from the current transport frame. */
- UINT avgBitRate; /* Average bit rate used for frame loss estimation. */
- UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame loss estimation */
- INT remainder; /* Reminder in division during lost access unit estimation. */
- INT missingAccessUnits; /* Estimated missing access units. */
- UINT burstPeriod; /* Data burst period in mili seconds. */
- UINT holdOffFrames; /* Amount of frames that were already hold off due to buffer fullness condition not being met. */
- UINT flags; /* Flags. */
+#define MHAS_CONFIG_PRESENT 0x001
+#define MHAS_UI_PRESENT 0x002
+
+struct TRANSPORTDEC {
+ TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */
+
+ CSTpCallBacks callbacks; /*!< Struct holding callback and its data */
+
+ FDK_BITSTREAM bitStream[1]; /* Bitstream reader */
+ UCHAR *bsBuffer; /* Internal bitstreamd data buffer */
+
+ transportdec_parser_t parser; /* Format specific parser structs. */
+
+ CSAudioSpecificConfig asc[(1 * 1) + 1]; /* Audio specific config from the last
+ config found. One additional
+ CSAudioSpecificConfig is used
+ temporarily for parsing. */
+ CCtrlCFGChange ctrlCFGChange[(1 * 1)]; /* Controls config change */
+
+ UINT globalFramePos; /* Global transport frame reference bit position. */
+ UINT accessUnitAnchor[1]; /* Current access unit start bit position. */
+ INT auLength[1]; /* Length of current access unit. */
+ INT numberOfRawDataBlocks; /* Current number of raw data blocks contained
+ remaining from the current transport frame. */
+ UINT avgBitRate; /* Average bit rate used for frame loss estimation. */
+ UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame
+ loss estimation */
+ INT remainder; /* Reminder in division during lost access unit estimation. */
+ INT missingAccessUnits; /* Estimated missing access units. */
+ UINT burstPeriod; /* Data burst period in mili seconds. */
+ UINT holdOffFrames; /* Amount of frames that were already hold off due to
+ buffer fullness condition not being met. */
+ UINT flags; /* Flags. */
+ INT targetLayout; /* CICP target layout. */
+ UINT *pLoudnessInfoSetPosition; /* Reference and start position (bits) and
+ length (bytes) of loudnessInfoSet within
+ rsv603daConfig. */
};
/* Flag bitmasks for "flags" member of struct TRANSPORTDEC */
-#define TPDEC_SYNCOK 1
-#define TPDEC_MINIMIZE_DELAY 2
+#define TPDEC_SYNCOK 1
+#define TPDEC_MINIMIZE_DELAY 2
#define TPDEC_IGNORE_BUFFERFULLNESS 4
-#define TPDEC_EARLY_CONFIG 8
-#define TPDEC_LOST_FRAMES_PENDING 16
-#define TPDEC_CONFIG_FOUND 32
+#define TPDEC_EARLY_CONFIG 8
+#define TPDEC_LOST_FRAMES_PENDING 16
+#define TPDEC_CONFIG_FOUND 32
+#define TPDEC_USE_ELEM_SKIPPING 64
-C_ALLOC_MEM(Ram_TransportDecoder, TRANSPORTDEC, 1)
-C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, TRANSPORTDEC_INBUF_SIZE)
+/* force config/content change */
+#define TPDEC_FORCE_CONFIG_CHANGE 1
+#define TPDEC_FORCE_CONTENT_CHANGE 2
+/* skip packet */
+#define TPDEC_SKIP_PACKET 1
+C_ALLOC_MEM(Ram_TransportDecoder, struct TRANSPORTDEC, 1)
+C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, (8192 * 4))
-
-HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const UINT flags)
-{
+HANDLE_TRANSPORTDEC transportDec_Open(const TRANSPORT_TYPE transportFmt,
+ const UINT flags, const UINT nrOfLayers) {
HANDLE_TRANSPORTDEC hInput;
hInput = GetRam_TransportDecoder(0);
- if ( hInput == NULL ) {
+ if (hInput == NULL) {
return NULL;
}
@@ -170,106 +201,355 @@ HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const
hInput->transportFmt = transportFmt;
switch (transportFmt) {
+ case TT_MP4_ADIF:
+ break;
+
+ case TT_MP4_ADTS:
+ if (flags & TP_FLAG_MPEG4)
+ hInput->parser.adts.decoderCanDoMpeg4 = 1;
+ else
+ hInput->parser.adts.decoderCanDoMpeg4 = 0;
+ adtsRead_CrcInit(&hInput->parser.adts);
+ hInput->parser.adts.BufferFullnesStartFlag = 1;
+ hInput->numberOfRawDataBlocks = 0;
+ break;
+
+ case TT_DRM:
+ drmRead_CrcInit(&hInput->parser.drm);
+ break;
+
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ hInput->parser.latm.usacExplicitCfgChanged = 0;
+ hInput->parser.latm.applyAsc = 1;
+ break;
+ case TT_MP4_LOAS:
+ hInput->parser.latm.usacExplicitCfgChanged = 0;
+ hInput->parser.latm.applyAsc = 1;
+ break;
+ case TT_MP4_RAW:
+ break;
- case TT_MP4_ADIF:
- break;
-
- case TT_MP4_ADTS:
- if (flags & TP_FLAG_MPEG4)
- hInput->parser.adts.decoderCanDoMpeg4 = 1;
- else
- hInput->parser.adts.decoderCanDoMpeg4 = 0;
- adtsRead_CrcInit(&hInput->parser.adts);
- hInput->parser.adts.BufferFullnesStartFlag = 1;
- hInput->numberOfRawDataBlocks = 0;
- break;
-
- case TT_DRM:
- drmRead_CrcInit(&hInput->parser.drm);
- break;
-
- case TT_MP4_LATM_MCP0:
- case TT_MP4_LATM_MCP1:
- case TT_MP4_LOAS:
- case TT_MP4_RAW:
- break;
-
- default:
- FreeRam_TransportDecoder(&hInput);
- hInput = NULL;
- break;
+ default:
+ FreeRam_TransportDecoder(&hInput);
+ hInput = NULL;
+ break;
}
if (hInput != NULL) {
/* Create bitstream */
- if ( TT_IS_PACKET(transportFmt) ) {
- hInput->bsBuffer = NULL;
- } else {
+ {
hInput->bsBuffer = GetRam_TransportDecoderBuffer(0);
if (hInput->bsBuffer == NULL) {
- transportDec_Close( &hInput );
- return NULL;
+ transportDec_Close(&hInput);
+ return NULL;
+ }
+ if (nrOfLayers > 1) {
+ transportDec_Close(&hInput);
+ return NULL;
+ }
+ for (UINT i = 0; i < nrOfLayers; i++) {
+ FDKinitBitStream(&hInput->bitStream[i], hInput->bsBuffer, (8192 * 4), 0,
+ BS_READER);
}
- FDKinitBitStream(&hInput->bitStream[0], hInput->bsBuffer, TRANSPORTDEC_INBUF_SIZE, 0, BS_READER);
}
-
hInput->burstPeriod = 0;
}
return hInput;
}
-TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *conf, const UINT length, UINT layer )
-{
- TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp,
+ UCHAR *conf, const UINT length,
+ UINT layer) {
+ int i;
- FDK_BITSTREAM bs;
- HANDLE_FDK_BITSTREAM hBs = &bs;
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
- FDKinitBitStream(hBs, conf, 0x10000000, length<<3, BS_READER);
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
int fConfigFound = 0;
- /* config transport decoder */
- switch (hTp->transportFmt) {
- case TT_MP4_LATM_MCP0:
- case TT_MP4_LATM_MCP1:
- case TT_MP4_LOAS:
- {
+ UCHAR configChanged = 0;
+ UCHAR configMode = AC_CM_DET_CFG_CHANGE;
+
+ UCHAR tmpConf[1024];
+ if (length > 1024) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ }
+ FDKmemcpy(tmpConf, conf, length);
+ FDKinitBitStream(hBs, tmpConf, 1024, length << 3, BS_READER);
+
+ for (i = 0; i < 2; i++) {
+ if (i > 0) {
+ FDKpushBack(hBs, length * 8 - FDKgetValidBits(hBs));
+ configMode = AC_CM_ALLOC_MEM;
+ }
+
+ /* config transport decoder */
+ switch (hTp->transportFmt) {
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LOAS: {
if (layer != 0) {
return TRANSPORTDEC_INVALID_PARAMETER;
}
CLatmDemux *pLatmDemux = &hTp->parser.latm;
- err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks, hTp->asc, &fConfigFound);
+ err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks,
+ hTp->asc, &fConfigFound,
+ configMode, configChanged);
if (err != TRANSPORTDEC_OK) {
return err;
}
- }
- break;
- default:
- fConfigFound = 1;
- err = AudioSpecificConfig_Parse(&hTp->asc[layer], hBs, 1, &hTp->callbacks);
- if (err == TRANSPORTDEC_OK) {
+ } break;
+ default:
+ fConfigFound = 1;
+ err = AudioSpecificConfig_Parse(&hTp->asc[(1 * 1)], hBs, 1,
+ &hTp->callbacks, configMode,
+ configChanged, AOT_NULL_OBJECT);
+ if (err == TRANSPORTDEC_OK) {
+ int errC;
+
+ hTp->asc[layer] = hTp->asc[(1 * 1)];
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
+ hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ break;
+ case TT_DRM:
+ fConfigFound = 1;
+ err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs, &hTp->callbacks,
+ configMode, configChanged);
+ if (err == TRANSPORTDEC_OK) {
+ int errC;
+
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
+ hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ break;
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
+ hTp->asc[layer].SbrConfigChanged ||
+ hTp->asc[layer].SacConfigChanged)) {
int errC;
- errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]);
+ configChanged = 1;
+ errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[layer]);
if (errC != 0) {
err = TRANSPORTDEC_PARSE_ERROR;
}
}
- break;
- case TT_DRM:
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK && fConfigFound) {
+ hTp->flags |= TPDEC_CONFIG_FOUND;
+ }
+
+ return err;
+}
+
+TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp,
+ UCHAR *newConfig,
+ const UINT newConfigLength,
+ const UCHAR buildUpStatus,
+ UCHAR *configChanged, UINT layer,
+ UCHAR *implicitExplicitCfgDiff) {
+ int errC;
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+ int fConfigFound = 0;
+ UCHAR configMode = AC_CM_ALLOC_MEM;
+ *implicitExplicitCfgDiff = 0;
+
+ FDK_ASSERT(hTp->asc->m_aot == AOT_USAC);
+
+ FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3,
+ BS_READER);
+
+ if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
+ (hTp->ctrlCFGChange[layer].buildUpStatus !=
+ TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
+ if (hTp->asc->m_aot == AOT_USAC) {
+ if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 ==
+ newConfigLength) {
+ if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig,
+ newConfigLength)) {
+ if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from
+ LOAS/LATM parser */
+ hTp->parser.latm.usacExplicitCfgChanged = 0;
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].flushStatus =
+ TPDEC_USAC_DASH_IPF_FLUSH_ON;
+ hTp->ctrlCFGChange[layer].buildUpCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ } else {
+ *configChanged = 0;
+ return err;
+ }
+ } else {
+ *implicitExplicitCfgDiff = 1;
+ }
+ } else {
+ *implicitExplicitCfgDiff = 1;
+ }
+ /* ISO/IEC 23003-3:2012/FDAM 3:2016(E) Annex F.2: explicit and implicit
+ * config shall be identical. */
+ if (*implicitExplicitCfgDiff) {
+ switch (hTp->transportFmt) {
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LOAS:
+ /* reset decoder to initial state to achieve definite behavior after
+ * error in config */
+ hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[layer]);
+ hTp->parser.latm.usacExplicitCfgChanged = 0;
+ hTp->parser.latm.applyAsc = 1;
+ err = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ {
+ if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) &&
+ (hTp->ctrlCFGChange[layer].buildUpStatus !=
+ TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) {
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ if (hTp->asc->m_aot == AOT_USAC) {
+ hTp->ctrlCFGChange[layer].flushStatus = TPDEC_USAC_DASH_IPF_FLUSH_ON;
+ }
+ }
+
+ if ((hTp->ctrlCFGChange[layer].flushStatus ==
+ TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
+ (hTp->ctrlCFGChange[layer].flushStatus ==
+ TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
+ SCHAR counter = 0;
+ if (hTp->asc->m_aot == AOT_USAC) {
+ counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES;
+ }
+ if (hTp->ctrlCFGChange[layer].flushCnt >= counter) {
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
+ hTp->ctrlCFGChange[layer].forceCfgChange = 0;
+ if (hTp->asc->m_aot == AOT_USAC) {
+ hTp->ctrlCFGChange[layer].buildUpCnt =
+ TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON;
+ }
+ }
+
+ /* Activate flush mode. After that continue with build up mode in core */
+ if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
+ &hTp->ctrlCFGChange[layer]) != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+
+ if ((hTp->ctrlCFGChange[layer].flushStatus ==
+ TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
+ (hTp->ctrlCFGChange[layer].flushStatus ==
+ TPDEC_USAC_DASH_IPF_FLUSH_ON)) {
+ hTp->ctrlCFGChange[layer].flushCnt++;
+ return err;
+ }
+ }
+
+ if (hTp->asc->m_aot == AOT_USAC) {
fConfigFound = 1;
- err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs);
+
if (err == TRANSPORTDEC_OK) {
- int errC;
+ *configChanged = 0;
+ configMode = AC_CM_DET_CFG_CHANGE;
- errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]);
- if (errC != 0) {
- err = TRANSPORTDEC_PARSE_ERROR;
+ for (int i = 0; i < 2; i++) {
+ if (i > 0) {
+ FDKpushBack(hBs, newConfigLength * 8 - FDKgetValidBits(hBs));
+ configMode = AC_CM_ALLOC_MEM;
+ }
+ /* config transport decoder */
+ err = AudioSpecificConfig_Parse(
+ &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode,
+ *configChanged, hTp->asc[layer].m_aot);
+ if (err == TRANSPORTDEC_OK) {
+ hTp->asc[layer] = hTp->asc[(1 * 1)];
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer],
+ hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ if ((i == 0) && (hTp->asc[layer].AacConfigChanged ||
+ hTp->asc[layer].SbrConfigChanged ||
+ hTp->asc[layer].SacConfigChanged)) {
+ *configChanged = 1;
+ errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[layer]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ }
+
+ /* if an error is detected terminate config parsing to avoid that an
+ * invalid config is accepted in the second pass */
+ if (err != TRANSPORTDEC_OK) {
+ break;
+ }
}
}
- break;
+ }
+
+ bail:
+ /* save new config */
+ if (err == TRANSPORTDEC_OK) {
+ if (hTp->asc->m_aot == AOT_USAC) {
+ hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3;
+ FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig,
+ newConfigLength);
+ /* in case of USAC reset transportDecoder variables here because
+ * otherwise without IPF they are not reset */
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
+ hTp->ctrlCFGChange[layer].buildUpCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ }
+ } else {
+ hTp->numberOfRawDataBlocks = 0;
+
+ /* If parsing error while config found, clear ctrlCFGChange-struct */
+ hTp->ctrlCFGChange[layer].flushCnt = 0;
+ hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF;
+ hTp->ctrlCFGChange[layer].buildUpCnt = 0;
+ hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ hTp->ctrlCFGChange[layer].cfgChanged = 0;
+ hTp->ctrlCFGChange[layer].contentChanged = 0;
+ hTp->ctrlCFGChange[layer].forceCfgChange = 0;
+
+ hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
+ &hTp->ctrlCFGChange[layer]);
+ }
}
if (err == TRANSPORTDEC_OK && fConfigFound) {
@@ -279,8 +559,9 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *
return err;
}
-int transportDec_RegisterAscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbUpdateConfig_t cbUpdateConfig, void* user_data)
-{
+int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUpdateConfig_t cbUpdateConfig,
+ void *user_data) {
if (hTpDec == NULL) {
return -1;
}
@@ -289,8 +570,30 @@ int transportDec_RegisterAscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbUpdate
return 0;
}
-int transportDec_RegisterSscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSsc_t cbSsc, void* user_data)
-{
+int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbFreeMem_t cbFreeMem,
+ void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbFreeMem = cbFreeMem;
+ hTpDec->callbacks.cbFreeMemData = user_data;
+ return 0;
+}
+
+int transportDec_RegisterCtrlCFGChangeCallback(
+ HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange,
+ void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange;
+ hTpDec->callbacks.cbCtrlCFGChangeData = user_data;
+ return 0;
+}
+
+int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbSsc_t cbSsc, void *user_data) {
if (hTpDec == NULL) {
return -1;
}
@@ -299,8 +602,8 @@ int transportDec_RegisterSscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSsc_t
return 0;
}
-int transportDec_RegisterSbrCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSbr_t cbSbr, void* user_data)
-{
+int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbSbr_t cbSbr, void *user_data) {
if (hTpDec == NULL) {
return -1;
}
@@ -309,65 +612,86 @@ int transportDec_RegisterSbrCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSbr_t
return 0;
}
-TRANSPORTDEC_ERROR transportDec_FillData(
- const HANDLE_TRANSPORTDEC hTp,
- UCHAR *pBuffer,
- const UINT bufferSize,
- UINT *pBytesValid,
- const INT layer )
-{
- HANDLE_FDK_BITSTREAM hBs;
+int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUsac_t cbUsac, void *user_data) {
+ if (hTpDec == NULL) {
+ return -1;
+ }
+ hTpDec->callbacks.cbUsac = cbUsac;
+ hTpDec->callbacks.cbUsacData = user_data;
+ return 0;
+}
- if ( (hTp == NULL)
- || (layer >= 2) ) {
- return TRANSPORTDEC_INVALID_PARAMETER;
+int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec,
+ const cbUniDrc_t cbUniDrc,
+ void *user_data,
+ UINT *pLoudnessInfoSetPosition) {
+ if (hTpDec == NULL) {
+ return -1;
}
- if (*pBytesValid == 0) {
- /* nothing to do */
- return TRANSPORTDEC_OK;
+ hTpDec->callbacks.cbUniDrc = cbUniDrc;
+ hTpDec->callbacks.cbUniDrcData = user_data;
+
+ hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition;
+ return 0;
+}
+
+TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp,
+ UCHAR *pBuffer, const UINT bufferSize,
+ UINT *pBytesValid, const INT layer) {
+ HANDLE_FDK_BITSTREAM hBs;
+
+ if ((hTp == NULL) || (layer >= 1)) {
+ return TRANSPORTDEC_INVALID_PARAMETER;
}
/* set bitbuffer shortcut */
hBs = &hTp->bitStream[layer];
- if ( TT_IS_PACKET(hTp->transportFmt) ) {
+ if (TT_IS_PACKET(hTp->transportFmt)) {
if (hTp->numberOfRawDataBlocks == 0) {
- /* For packet based transport, pass input buffer to bitbuffer without copying the data.
- Unfortunately we do not know the actual buffer size. And the FDK bit buffer implementation
- needs a number 2^x. So we assume the maximum of 48 channels with 6144 bits per channel
- and round it up to the next power of 2 => 65536 bytes */
- FDKinitBitStream(hBs, pBuffer, 0x10000, (*pBytesValid)<<3, BS_READER);
- *pBytesValid = 0;
+ FDKresetBitbuffer(hBs);
+ FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
+ if (*pBytesValid != 0) {
+ return TRANSPORTDEC_TOO_MANY_BITS;
+ }
}
} else {
/* ... else feed bitbuffer with new stream data (append). */
+
+ if (*pBytesValid == 0) {
+ /* nothing to do */
+ return TRANSPORTDEC_OK;
+ }
+
if (hTp->numberOfRawDataBlocks <= 0) {
- FDKfeedBuffer (hBs, pBuffer, bufferSize, pBytesValid) ;
+ FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid);
}
}
return TRANSPORTDEC_OK;
}
-HANDLE_FDK_BITSTREAM transportDec_GetBitstream( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
-{
+HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
return &hTp->bitStream[layer];
}
-TRANSPORT_TYPE transportDec_GetFormat( const HANDLE_TRANSPORTDEC hTp )
-{
+TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) {
return hTp->transportFmt;
}
-INT transportDec_GetBufferFullness( const HANDLE_TRANSPORTDEC hTp )
-{
+INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) {
INT bufferFullness = -1;
switch (hTp->transportFmt) {
case TT_MP4_ADTS:
if (hTp->parser.adts.bs.adts_fullness != 0x7ff) {
- bufferFullness = hTp->parser.adts.bs.frame_length*8 + hTp->parser.adts.bs.adts_fullness * 32 * getNumberOfEffectiveChannels(hTp->parser.adts.bs.channel_config);
+ bufferFullness = hTp->parser.adts.bs.frame_length * 8 +
+ hTp->parser.adts.bs.adts_fullness * 32 *
+ getNumberOfEffectiveChannels(
+ hTp->parser.adts.bs.channel_config);
}
break;
case TT_MP4_LOAS:
@@ -389,31 +713,37 @@ INT transportDec_GetBufferFullness( const HANDLE_TRANSPORTDEC hTp )
* \param hTp transport decoder handle.
* \return error code.
*/
-static
-TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp)
-{
+static TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(
+ HANDLE_TRANSPORTDEC hTp) {
HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
switch (hTp->transportFmt) {
+ case TT_MP4_ADIF:
+ /* Do byte align at the end of raw_data_block() because UsacFrame() is not
+ * byte aligned. */
+ FDKbyteAlign(hBs, hTp->accessUnitAnchor[0]);
+ break;
case TT_MP4_LOAS:
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1:
- if ( hTp->numberOfRawDataBlocks == 0 )
- {
+ if (hTp->numberOfRawDataBlocks == 0) {
/* Do byte align at the end of AudioMuxElement. */
FDKbyteAlign(hBs, hTp->globalFramePos);
/* Check global frame length */
- if (hTp->transportFmt == TT_MP4_LOAS && hTp->parser.latm.m_audioMuxLengthBytes > 0)
- {
+ if (hTp->transportFmt == TT_MP4_LOAS &&
+ hTp->parser.latm.m_audioMuxLengthBytes > 0) {
int loasOffset;
- loasOffset = (hTp->parser.latm.m_audioMuxLengthBytes*8 + FDKgetValidBits(hBs)) - hTp->globalFramePos;
+ loasOffset = (hTp->parser.latm.m_audioMuxLengthBytes * 8 +
+ FDKgetValidBits(hBs)) -
+ hTp->globalFramePos;
if (loasOffset != 0) {
FDKpushBiDirectional(hBs, loasOffset);
- /* For ELD and other payloads there is an unknown amount of padding, so ignore unread bits, but
- throw an error only if too many bits where read. */
+ /* For ELD and other payloads there is an unknown amount of padding,
+ so ignore unread bits, but throw an error only if too many bits
+ where read. */
if (loasOffset < 0) {
err = TRANSPORTDEC_PARSE_ERROR;
}
@@ -423,28 +753,34 @@ TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp)
break;
case TT_MP4_ADTS:
- if (hTp->parser.adts.bs.protection_absent == 0)
- {
+ if (hTp->parser.adts.bs.protection_absent == 0) {
int offset;
/* Calculate offset to end of AU */
- offset = hTp->parser.adts.rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks]<<3;
- /* CAUTION: The PCE (if available) is declared to be a part of the header! */
- offset -= hTp->accessUnitAnchor[0] - FDKgetValidBits(hBs) + 16 + hTp->parser.adts.bs.num_pce_bits;
+ offset = hTp->parser.adts
+ .rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks -
+ hTp->numberOfRawDataBlocks]
+ << 3;
+ /* CAUTION: The PCE (if available) is declared to be a part of the
+ * header! */
+ offset -= (INT)hTp->accessUnitAnchor[0] - (INT)FDKgetValidBits(hBs) +
+ 16 + hTp->parser.adts.bs.num_pce_bits;
FDKpushBiDirectional(hBs, offset);
}
- if (hTp->parser.adts.bs.num_raw_blocks > 0 && hTp->parser.adts.bs.protection_absent == 0) {
- /* Note this CRC read currently happens twice because of transportDec_CrcCheck() */
+ if (hTp->parser.adts.bs.num_raw_blocks > 0 &&
+ hTp->parser.adts.bs.protection_absent == 0) {
+ /* Note this CRC read currently happens twice because of
+ * transportDec_CrcCheck() */
hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
}
- if ( hTp->numberOfRawDataBlocks == 0 )
- {
+ if (hTp->numberOfRawDataBlocks == 0) {
/* Check global frame length */
- if (hTp->parser.adts.bs.protection_absent == 0)
- {
+ if (hTp->parser.adts.bs.protection_absent == 0) {
int offset;
- offset = (hTp->parser.adts.bs.frame_length*8 - ADTS_SYNCLENGTH + FDKgetValidBits(hBs)) - hTp->globalFramePos;
+ offset = (hTp->parser.adts.bs.frame_length * 8 - ADTS_SYNCLENGTH +
+ (INT)FDKgetValidBits(hBs)) -
+ (INT)hTp->globalFramePos;
if (offset != 0) {
FDKpushBiDirectional(hBs, offset);
}
@@ -459,41 +795,39 @@ TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp)
return err;
}
-
/**
- * \brief Determine additional buffer fullness contraint due to burst data reception.
- * The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a precondition.
+ * \brief Determine additional buffer fullness contraint due to burst data
+ * reception. The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a
+ * precondition.
* \param hTp transport decoder handle.
- * \param bufferFullness the buffer fullness value of the first frame to be decoded.
- * \param bitsAvail the amount of available bits at the end of the first frame to be decoded.
+ * \param bufferFullness the buffer fullness value of the first frame to be
+ * decoded.
+ * \param bitsAvail the amount of available bits at the end of the first frame
+ * to be decoded.
* \return error code
*/
-static
-TRANSPORTDEC_ERROR additionalHoldOffNeeded(
- HANDLE_TRANSPORTDEC hTp,
- INT bufferFullness,
- INT bitsAvail
- )
-{
+static TRANSPORTDEC_ERROR additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp,
+ INT bufferFullness,
+ INT bitsAvail) {
INT checkLengthBits, avgBitsPerFrame;
INT maxAU; /* maximum number of frames per Master Frame */
INT samplesPerFrame = hTp->asc->m_samplesPerFrame;
INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency;
- if ( (hTp->avgBitRate == 0) || (hTp->burstPeriod == 0) ) {
+ if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) {
return TRANSPORTDEC_OK;
}
- if ( (samplesPerFrame == 0 ) || (samplingFrequency == 0) ) {
+ if ((samplesPerFrame == 0) || (samplingFrequency == 0)) {
return TRANSPORTDEC_NOT_ENOUGH_BITS;
}
/* One Master Frame is sent every hTp->burstPeriod ms */
- maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame*1000 - 1);
- maxAU = maxAU / (samplesPerFrame*1000);
+ maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame * 1000 - 1);
+ maxAU = maxAU / (samplesPerFrame * 1000);
/* Subtract number of frames which were already held off. */
maxAU -= hTp->holdOffFrames;
- avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency-1);
+ avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency - 1);
avgBitsPerFrame = avgBitsPerFrame / samplingFrequency;
/* Consider worst case of bufferFullness quantization. */
@@ -505,41 +839,35 @@ TRANSPORTDEC_ERROR additionalHoldOffNeeded(
case TT_MP4_LATM_MCP1:
bufferFullness += 31;
break;
- default:
- break;
+ default: /* added to avoid compiler warning */
+ break; /* added to avoid compiler warning */
}
- checkLengthBits = bufferFullness + (maxAU-1)*avgBitsPerFrame;
+ checkLengthBits = bufferFullness + (maxAU - 1) * avgBitsPerFrame;
/* Check if buffer is big enough to fullfill buffer fullness condition */
- if ( (checkLengthBits /*+headerBits*/) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
+ if ((checkLengthBits /*+headerBits*/) > (((8192 * 4) << 3) - 7)) {
return TRANSPORTDEC_SYNC_ERROR;
}
- if ( bitsAvail < checkLengthBits ) {
+ if (bitsAvail < checkLengthBits) {
return TRANSPORTDEC_NOT_ENOUGH_BITS;
- }
- else {
+ } else {
return TRANSPORTDEC_OK;
}
}
static TRANSPORTDEC_ERROR transportDec_readHeader(
- HANDLE_TRANSPORTDEC hTp,
- HANDLE_FDK_BITSTREAM hBs,
- int syncLength,
- int ignoreBufferFullness,
- int *pRawDataBlockLength,
- int *pfTraverseMoreFrames,
- int *pSyncLayerFrameBits,
- int *pfConfigFound,
- int *pHeaderBits
- )
-{
+ HANDLE_TRANSPORTDEC hTp, HANDLE_FDK_BITSTREAM hBs, int syncLength,
+ int ignoreBufferFullness, int *pRawDataBlockLength,
+ int *pfTraverseMoreFrames, int *pSyncLayerFrameBits, int *pfConfigFound,
+ int *pHeaderBits) {
TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
int rawDataBlockLength = *pRawDataBlockLength;
- int fTraverseMoreFrames = (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
- int syncLayerFrameBits = (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
+ int fTraverseMoreFrames =
+ (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
+ int syncLayerFrameBits =
+ (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
int startPos;
@@ -547,46 +875,74 @@ static TRANSPORTDEC_ERROR transportDec_readHeader(
switch (hTp->transportFmt) {
case TT_MP4_ADTS:
- if (hTp->numberOfRawDataBlocks <= 0)
- {
- int errC;
+ if (hTp->numberOfRawDataBlocks <= 0) {
+ int i, errC;
hTp->globalFramePos = FDKgetValidBits(hBs);
- /* Parse ADTS header */
- err = adtsRead_DecodeHeader( &hTp->parser.adts, &hTp->asc[0], hBs, ignoreBufferFullness );
- if (err != TRANSPORTDEC_OK) {
- if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
- err = TRANSPORTDEC_SYNC_ERROR;
+ UCHAR configChanged = 0;
+ UCHAR configMode = AC_CM_DET_CFG_CHANGE;
+
+ for (i = 0; i < 2; i++) {
+ if (i > 0) {
+ FDKpushBack(hBs,
+ (INT)hTp->globalFramePos - (INT)FDKgetValidBits(hBs));
+ configMode = AC_CM_ALLOC_MEM;
}
- } else {
- errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
- if (errC != 0) {
- if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
- err = TRANSPORTDEC_NEED_TO_RESTART;
- goto bail;
- } else {
+
+ /* Parse ADTS header */
+ err = adtsRead_DecodeHeader(&hTp->parser.adts, &hTp->asc[0], hBs,
+ ignoreBufferFullness);
+ if (err != TRANSPORTDEC_OK) {
+ if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
err = TRANSPORTDEC_SYNC_ERROR;
}
} else {
- fConfigFound = 1;
- hTp->numberOfRawDataBlocks = hTp->parser.adts.bs.num_raw_blocks+1;
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
+ &configChanged);
+ if (errC != 0) {
+ if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
+ err = TRANSPORTDEC_NEED_TO_RESTART;
+ goto bail;
+ } else {
+ err = TRANSPORTDEC_SYNC_ERROR;
+ }
+ } else {
+ fConfigFound = 1;
+ hTp->numberOfRawDataBlocks =
+ hTp->parser.adts.bs.num_raw_blocks + 1;
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ if ((i == 0) && configChanged) {
+ errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[0]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
}
}
- }
- else {
- /* Reset CRC because the next bits are the beginning of a raw_data_block() */
+ } else {
+ /* Reset CRC because the next bits are the beginning of a
+ * raw_data_block() */
FDKcrcReset(&hTp->parser.adts.crcInfo);
hTp->parser.adts.bs.num_pce_bits = 0;
}
if (err == TRANSPORTDEC_OK) {
hTp->numberOfRawDataBlocks--;
- rawDataBlockLength = adtsRead_GetRawDataBlockLength(&hTp->parser.adts, (hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks));
+ rawDataBlockLength = adtsRead_GetRawDataBlockLength(
+ &hTp->parser.adts,
+ (hTp->parser.adts.bs.num_raw_blocks - hTp->numberOfRawDataBlocks));
if (rawDataBlockLength <= 0) {
/* No further frame traversal possible. */
fTraverseMoreFrames = 0;
}
- syncLayerFrameBits = (hTp->parser.adts.bs.frame_length<<3) - (startPos - FDKgetValidBits(hBs)) - syncLength;
+ syncLayerFrameBits = (hTp->parser.adts.bs.frame_length << 3) -
+ ((INT)startPos - (INT)FDKgetValidBits(hBs)) -
+ syncLength;
if (syncLayerFrameBits <= 0) {
err = TRANSPORTDEC_SYNC_ERROR;
}
@@ -595,35 +951,30 @@ static TRANSPORTDEC_ERROR transportDec_readHeader(
}
break;
case TT_MP4_LOAS:
- if (hTp->numberOfRawDataBlocks <= 0)
- {
+ if (hTp->numberOfRawDataBlocks <= 0) {
syncLayerFrameBits = FDKreadBits(hBs, 13);
hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
syncLayerFrameBits <<= 3;
}
case TT_MP4_LATM_MCP1:
case TT_MP4_LATM_MCP0:
- if (hTp->numberOfRawDataBlocks <= 0)
- {
+ if (hTp->numberOfRawDataBlocks <= 0) {
hTp->globalFramePos = FDKgetValidBits(hBs);
- err = CLatmDemux_Read(
- hBs,
- &hTp->parser.latm,
- hTp->transportFmt,
- &hTp->callbacks,
- hTp->asc,
- &fConfigFound,
- ignoreBufferFullness);
+ err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt,
+ &hTp->callbacks, hTp->asc, &fConfigFound,
+ ignoreBufferFullness);
if (err != TRANSPORTDEC_OK) {
- if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
+ if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) &&
+ !TPDEC_IS_FATAL_ERROR(err)) {
err = TRANSPORTDEC_SYNC_ERROR;
}
} else {
- hTp->numberOfRawDataBlocks = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
+ hTp->numberOfRawDataBlocks =
+ CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
if (hTp->transportFmt == TT_MP4_LOAS) {
- syncLayerFrameBits -= startPos - FDKgetValidBits(hBs) - (13);
+ syncLayerFrameBits -= startPos - FDKgetValidBits(hBs) - (13);
}
}
} else {
@@ -633,17 +984,20 @@ static TRANSPORTDEC_ERROR transportDec_readHeader(
}
}
if (err == TRANSPORTDEC_OK) {
- rawDataBlockLength = CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm);
+ int layer;
+ rawDataBlockLength = 0;
+ for (layer = 0;
+ layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0);
+ layer += 1) {
+ rawDataBlockLength +=
+ CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer);
+ }
hTp->numberOfRawDataBlocks--;
} else {
hTp->numberOfRawDataBlocks = 0;
}
break;
- default:
- {
- syncLayerFrameBits = 0;
- }
- break;
+ default: { syncLayerFrameBits = 0; } break;
}
bail:
@@ -653,6 +1007,24 @@ bail:
if (pHeaderBits != NULL) {
*pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
}
+
+ for (int i = 0; i < (1 * 1); i++) {
+ /* If parsing error while config found, clear ctrlCFGChange-struct */
+ if (hTp->ctrlCFGChange[i].cfgChanged && err != TRANSPORTDEC_OK) {
+ hTp->numberOfRawDataBlocks = 0;
+ hTp->ctrlCFGChange[i].flushCnt = 0;
+ hTp->ctrlCFGChange[i].flushStatus = TPDEC_FLUSH_OFF;
+ hTp->ctrlCFGChange[i].buildUpCnt = 0;
+ hTp->ctrlCFGChange[i].buildUpStatus = TPDEC_BUILD_UP_OFF;
+ hTp->ctrlCFGChange[i].cfgChanged = 0;
+ hTp->ctrlCFGChange[i].contentChanged = 0;
+ hTp->ctrlCFGChange[i].forceCfgChange = 0;
+
+ hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData,
+ &hTp->ctrlCFGChange[i]);
+ }
+ }
+
if (pfConfigFound != NULL) {
*pfConfigFound = fConfigFound;
}
@@ -660,12 +1032,9 @@ bail:
if (pfTraverseMoreFrames != NULL) {
*pfTraverseMoreFrames = fTraverseMoreFrames;
}
- if (pSyncLayerFrameBits != NULL) {
+ if (pSyncLayerFrameBits != NULL) {
*pSyncLayerFrameBits = syncLayerFrameBits;
}
- if (pfConfigFound != NULL) {
- *pfConfigFound = fConfigFound;
- }
return err;
}
@@ -673,12 +1042,8 @@ bail:
/* How many bits to advance for synchronization search. */
#define TPDEC_SYNCSKIP 8
-static
-TRANSPORTDEC_ERROR synchronization(
- HANDLE_TRANSPORTDEC hTp,
- INT *pHeaderBits
- )
-{
+static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp,
+ INT *pHeaderBits) {
TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
@@ -686,14 +1051,20 @@ TRANSPORTDEC_ERROR synchronization(
INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
INT totalBits;
INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
- INT numFramesTraversed = 0, fTraverseMoreFrames, fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
- INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious, globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
- INT ignoreBufferFullness = hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK);
+ INT numFramesTraversed = 0, fTraverseMoreFrames,
+ fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
+ INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious,
+ globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
+ INT ignoreBufferFullness =
+ hTp->flags &
+ (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK);
+ UINT endTpFrameBitsPrevious = 0;
/* Synch parameters */
- INT syncLength; /* Length of sync word in bits */
- UINT syncWord; /* Sync word to be found */
- UINT syncMask; /* Mask for sync word (for adding one bit, so comprising one bit less) */
+ INT syncLength; /* Length of sync word in bits */
+ UINT syncWord; /* Sync word to be found */
+ UINT syncMask; /* Mask for sync word (for adding one bit, so comprising one
+ bit less) */
C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);
totalBits = (INT)FDKgetValidBits(hBs);
@@ -703,7 +1074,9 @@ TRANSPORTDEC_ERROR synchronization(
goto bail;
}
- fTraverseMoreFrames = (hTp->flags & (TPDEC_MINIMIZE_DELAY|TPDEC_EARLY_CONFIG)) && ! (hTp->flags & TPDEC_SYNCOK);
+ fTraverseMoreFrames =
+ (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) &&
+ !(hTp->flags & TPDEC_SYNCOK);
/* Set transport specific sync parameters */
switch (hTp->transportFmt) {
@@ -721,12 +1094,13 @@ TRANSPORTDEC_ERROR synchronization(
break;
}
- syncMask = (1<<syncLength)-1;
+ syncMask = (1 << syncLength) - 1;
do {
- INT bitsAvail = 0; /* Bits available in bitstream buffer */
- INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries */
- UINT synch; /* Current sync word read from bitstream */
+ INT bitsAvail = 0; /* Bits available in bitstream buffer */
+ INT checkLengthBits; /* Helper to check remaining bits and buffer boundaries
+ */
+ UINT synch; /* Current sync word read from bitstream */
headerBitsPrevious = headerBits;
@@ -735,21 +1109,22 @@ TRANSPORTDEC_ERROR synchronization(
if (hTp->numberOfRawDataBlocks == 0) {
/* search synchword */
- FDK_ASSERT( (bitsAvail % TPDEC_SYNCSKIP) == 0);
+ FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0);
- if ((bitsAvail-syncLength) < TPDEC_SYNCSKIP) {
+ if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) {
err = TRANSPORTDEC_NOT_ENOUGH_BITS;
headerBits = 0;
} else {
-
synch = FDKreadBits(hBs, syncLength);
- if ( !(hTp->flags & TPDEC_SYNCOK) ) {
- for (; (bitsAvail-syncLength) >= TPDEC_SYNCSKIP; bitsAvail-=TPDEC_SYNCSKIP) {
+ if (!(hTp->flags & TPDEC_SYNCOK)) {
+ for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP;
+ bitsAvail -= TPDEC_SYNCSKIP) {
if (synch == syncWord) {
break;
}
- synch = ((synch << TPDEC_SYNCSKIP) & syncMask) | FDKreadBits(hBs, TPDEC_SYNCSKIP);
+ synch = ((synch << TPDEC_SYNCSKIP) & syncMask) |
+ FDKreadBits(hBs, TPDEC_SYNCSKIP);
}
}
if (synch != syncWord) {
@@ -770,44 +1145,40 @@ TRANSPORTDEC_ERROR synchronization(
/* Parse transport header (raw data block granularity) */
- if (err == TRANSPORTDEC_OK )
- {
- err = transportDec_readHeader(
- hTp,
- hBs,
- syncLength,
- ignoreBufferFullness,
- &rawDataBlockLength,
- &fTraverseMoreFrames,
- &syncLayerFrameBits,
- &fConfigFound,
- &headerBits
- );
+ if (err == TRANSPORTDEC_OK) {
+ err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness,
+ &rawDataBlockLength, &fTraverseMoreFrames,
+ &syncLayerFrameBits, &fConfigFound,
+ &headerBits);
+ if (TPDEC_IS_FATAL_ERROR(err)) {
+ goto bail;
+ }
}
bitsAvail -= headerBits;
- checkLengthBits = syncLayerFrameBits;
+ checkLengthBits = syncLayerFrameBits;
/* Check if the whole frame would fit the bitstream buffer */
if (err == TRANSPORTDEC_OK) {
- if ( (checkLengthBits+headerBits) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
+ if ((checkLengthBits + headerBits) > (((8192 * 4) << 3) - 7)) {
/* We assume that the size of the transport bit buffer has been
chosen to meet all system requirements, thus this condition
is considered a synchronisation error. */
err = TRANSPORTDEC_SYNC_ERROR;
} else {
- if ( bitsAvail < checkLengthBits ) {
+ if (bitsAvail < checkLengthBits) {
err = TRANSPORTDEC_NOT_ENOUGH_BITS;
}
}
}
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
+ /* Enforce reading of new data */
+ hTp->numberOfRawDataBlocks = 0;
break;
}
-
if (err == TRANSPORTDEC_SYNC_ERROR) {
int bits;
@@ -816,38 +1187,39 @@ TRANSPORTDEC_ERROR synchronization(
/* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
- /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead next time. */
+ /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead
+ * next time. */
FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
- bitsAvail += headerBits - TPDEC_SYNCSKIP - bits;
headerBits = 0;
}
/* Frame traversal */
- if ( fTraverseMoreFrames )
- {
+ if (fTraverseMoreFrames) {
/* Save parser context for early config discovery "rewind all frames" */
- if ( (hTp->flags & TPDEC_EARLY_CONFIG) && !(hTp->flags & TPDEC_MINIMIZE_DELAY))
- {
- /* ignore buffer fullness if just traversing additional frames for ECD */
+ if ((hTp->flags & TPDEC_EARLY_CONFIG) &&
+ !(hTp->flags & TPDEC_MINIMIZE_DELAY)) {
+ /* ignore buffer fullness if just traversing additional frames for ECD
+ */
ignoreBufferFullness = 1;
/* Save context in order to return later */
- if ( err == TRANSPORTDEC_OK && startPosFirstFrame == -1 ) {
+ if (err == TRANSPORTDEC_OK && startPosFirstFrame == -1) {
startPosFirstFrame = FDKgetValidBits(hBs);
numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
globalFramePosFirstFrame = hTp->globalFramePos;
rawDataBlockLengthFirstFrame = rawDataBlockLength;
headerBitsFirstFrame = headerBits;
errFirstFrame = err;
- FDKmemcpy(contextFirstFrame, &hTp->parser, sizeof(transportdec_parser_t));
+ FDKmemcpy(contextFirstFrame, &hTp->parser,
+ sizeof(transportdec_parser_t));
}
- /* Break when config was found or it is not possible anymore to find a config */
- if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK))
- {
+ /* Break when config was found or it is not possible anymore to find a
+ * config */
+ if (startPosFirstFrame != -1 &&
+ (fConfigFound || err != TRANSPORTDEC_OK)) {
/* In case of ECD and sync error, do not rewind anywhere. */
- if (err == TRANSPORTDEC_SYNC_ERROR)
- {
+ if (err == TRANSPORTDEC_SYNC_ERROR) {
startPosFirstFrame = -1;
fConfigFound = 0;
numFramesTraversed = 0;
@@ -858,16 +1230,18 @@ TRANSPORTDEC_ERROR synchronization(
if (err == TRANSPORTDEC_OK) {
FDKpushFor(hBs, rawDataBlockLength);
- bitsAvail -= rawDataBlockLength;
numFramesTraversed++;
+ endTpFrameBitsPrevious = (INT)FDKgetValidBits(hBs);
/* Ignore error here itentionally. */
transportDec_AdjustEndOfAccessUnit(hTp);
+ endTpFrameBitsPrevious -= FDKgetValidBits(hBs);
}
}
- } while ( fTraverseMoreFrames || (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
+ } while (fTraverseMoreFrames ||
+ (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));
/* Restore context in case of ECD frame traversal */
- if ( startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK) ) {
+ if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
@@ -876,32 +1250,35 @@ TRANSPORTDEC_ERROR synchronization(
headerBits = headerBitsFirstFrame;
err = errFirstFrame;
numFramesTraversed = 0;
- }
+ }
/* Additional burst data mode buffer fullness check. */
- if ( !(hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK)) && err == TRANSPORTDEC_OK) {
- err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), FDKgetValidBits(hBs) - syncLayerFrameBits);
+ if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS |
+ TPDEC_SYNCOK)) &&
+ err == TRANSPORTDEC_OK) {
+ err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp),
+ FDKgetValidBits(hBs) - syncLayerFrameBits);
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
hTp->holdOffFrames++;
}
}
-
+
/* Rewind for retry because of not enough bits */
if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
FDKpushBack(hBs, headerBits);
headerBits = 0;
- }
- else {
+ } else {
/* reset hold off frame counter */
hTp->holdOffFrames = 0;
}
/* Return to last good frame in case of frame traversal but not ECD. */
if (numFramesTraversed > 0) {
- FDKpushBack(hBs, rawDataBlockLengthPrevious);
+ FDKpushBack(hBs, rawDataBlockLengthPrevious + endTpFrameBitsPrevious);
if (err != TRANSPORTDEC_OK) {
hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
headerBits = headerBitsPrevious;
+ rawDataBlockLength = rawDataBlockLengthPrevious;
}
err = TRANSPORTDEC_OK;
}
@@ -909,10 +1286,13 @@ TRANSPORTDEC_ERROR synchronization(
bail:
hTp->auLength[0] = rawDataBlockLength;
- /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, were the bit buffer is already full,
- or no new burst packet fits. Recover by advancing the bit buffer. */
- if ( (TRANSPORTDEC_NOT_ENOUGH_BITS == err) && (FDKgetValidBits(hBs) >= ((TRANSPORTDEC_INBUF_SIZE*8 - ((hTp->avgBitRate*hTp->burstPeriod)/1000)) - 7)) )
- {
+ /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, where the bit
+ buffer is already full, or no new burst packet fits. Recover by advancing
+ the bit buffer. */
+ if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&
+ (FDKgetValidBits(hBs) >=
+ (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) -
+ 7))) {
FDKpushFor(hBs, TPDEC_SYNCSKIP);
err = TRANSPORTDEC_SYNC_ERROR;
}
@@ -939,16 +1319,14 @@ bail:
}
/**
- * \brief Synchronize to stream and estimate the amount of missing access units due
- * to a current synchronization error in case of constant average bit rate.
+ * \brief Synchronize to stream and estimate the amount of missing access units
+ * due to a current synchronization error in case of constant average bit rate.
*/
-static
-TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT layer )
-{
-
+static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
- INT nAU = -1;
+
INT headerBits;
INT bitDistance, bfDelta;
@@ -957,16 +1335,16 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT
error = synchronization(hTp, &headerBits);
bitDistance -= FDKgetValidBits(hBs);
-
FDK_ASSERT(bitDistance >= 0);
- if (error == TRANSPORTDEC_SYNC_ERROR || (hTp->flags & TPDEC_LOST_FRAMES_PENDING))
- {
+ INT nAU = -1;
+
+ if (error == TRANSPORTDEC_SYNC_ERROR ||
+ (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
/* Check if estimating lost access units is feasible. */
- if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 && hTp->asc[0].m_samplingFrequency > 0)
- {
- if (error == TRANSPORTDEC_OK)
- {
+ if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 &&
+ hTp->asc[0].m_samplingFrequency > 0) {
+ if (error == TRANSPORTDEC_OK) {
int aj;
aj = transportDec_GetBufferFullness(hTp);
@@ -978,15 +1356,15 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT
/* sync was ok: last of a series of bad access units. */
hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
/* Add up bitDistance until end of the current frame. Later we substract
- this frame from the grand total, since this current successfully synchronized
- frame should not be skipped of course; but it must be accounted into the
- bufferfulness math. */
+ this frame from the grand total, since this current successfully
+ synchronized frame should not be skipped of course; but it must be
+ accounted into the bufferfulness math. */
bitDistance += hTp->auLength[0];
} else {
- if ( !(hTp->flags & TPDEC_LOST_FRAMES_PENDING) ) {
+ if (!(hTp->flags & TPDEC_LOST_FRAMES_PENDING)) {
/* sync not ok: one of many bad access units. */
hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
- bfDelta = - (INT)hTp->lastValidBufferFullness;
+ bfDelta = -(INT)hTp->lastValidBufferFullness;
} else {
bfDelta = 0;
}
@@ -996,7 +1374,8 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT
int num, denom;
/* Obtain estimate of number of lost frames */
- num = hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + hTp->remainder;
+ num = hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) +
+ hTp->remainder;
denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
if (num > 0) {
nAU = num / denom;
@@ -1005,23 +1384,20 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT
hTp->remainder = num;
}
- if (error == TRANSPORTDEC_OK)
- {
- /* Final adjustment of remainder, taken -1 into account because current
- frame should not be skipped, thus substract -1 or do nothing instead
- of +1-1 accordingly. */
- if ( (denom - hTp->remainder) >= hTp->remainder ) {
+ if (error == TRANSPORTDEC_OK) {
+ /* Final adjustment of remainder, taken -1 into account because
+ current frame should not be skipped, thus substract -1 or do
+ nothing instead of +1-1 accordingly. */
+ if ((denom - hTp->remainder) >= hTp->remainder) {
nAU--;
}
-
+
if (nAU < 0) {
- /* There was one frame too much concealed, so unfortunately we will have to skip one good frame. */
+ /* There was one frame too much concealed, so unfortunately we will
+ * have to skip one good frame. */
transportDec_EndAccessUnit(hTp);
- error = synchronization(hTp, &headerBits);
+ error = synchronization(hTp, &headerBits);
nAU = -1;
-#ifdef DEBUG
- FDKprintf("ERROR: Bufferfullness accounting failed. remainder=%d, nAU=%d\n", hTp->remainder, nAU);
-#endif
}
hTp->remainder = 0;
/* Enforce last missed frames to be concealed. */
@@ -1033,9 +1409,10 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT
}
}
- /* Be sure that lost frames are handled correctly. This is necessary due to some
- sync error sequences where later it turns out that there is not enough data, but
- the bits upto the sync word are discarded, thus causing a value of nAU > 0 */
+ /* Be sure that lost frames are handled correctly. This is necessary due to
+ some sync error sequences where later it turns out that there is not enough
+ data, but the bits upto the sync word are discarded, thus causing a value
+ of nAU > 0 */
if (nAU > 0) {
error = TRANSPORTDEC_SYNC_ERROR;
}
@@ -1046,8 +1423,8 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT
}
/* returns error code */
-TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
-{
+TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
HANDLE_FDK_BITSTREAM hBs;
@@ -1058,41 +1435,66 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
hBs = &hTp->bitStream[layer];
if ((INT)FDKgetValidBits(hBs) <= 0) {
+ /* This is only relevant for RAW and ADIF cases.
+ * For streaming formats err will get overwritten. */
err = TRANSPORTDEC_NOT_ENOUGH_BITS;
+ hTp->numberOfRawDataBlocks = 0;
}
switch (hTp->transportFmt) {
-
case TT_MP4_ADIF:
/* Read header if not already done */
- if (!(hTp->flags & TPDEC_CONFIG_FOUND))
- {
+ if (!(hTp->flags & TPDEC_CONFIG_FOUND)) {
+ int i;
CProgramConfig *pce;
+ INT bsStart = FDKgetValidBits(hBs);
+ UCHAR configChanged = 0;
+ UCHAR configMode = AC_CM_DET_CFG_CHANGE;
+
+ for (i = 0; i < 2; i++) {
+ if (i > 0) {
+ FDKpushBack(hBs, bsStart - FDKgetValidBits(hBs));
+ configMode = AC_CM_ALLOC_MEM;
+ }
- AudioSpecificConfig_Init(&hTp->asc[0]);
- pce = &hTp->asc[0].m_progrConfigElement;
- err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
- if (err)
- goto bail;
-
- /* Map adif header to ASC */
- hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
- hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
- hTp->asc[0].m_samplingFrequency = SamplingRateTable[pce->SamplingFrequencyIndex];
- hTp->asc[0].m_channelConfiguration = 0;
- hTp->asc[0].m_samplesPerFrame = 1024;
- hTp->avgBitRate = hTp->parser.adif.BitRate;
-
- /* Call callback to decoder. */
- {
- int errC;
+ AudioSpecificConfig_Init(&hTp->asc[0]);
+ pce = &hTp->asc[0].m_progrConfigElement;
+ err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
+ if (err) goto bail;
+
+ /* Map adif header to ASC */
+ hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
+ hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
+ hTp->asc[0].m_samplingFrequency =
+ SamplingRateTable[pce->SamplingFrequencyIndex];
+ hTp->asc[0].m_channelConfiguration = 0;
+ hTp->asc[0].m_samplesPerFrame = 1024;
+ hTp->avgBitRate = hTp->parser.adif.BitRate;
+
+ /* Call callback to decoder. */
+ {
+ int errC;
- errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
- if (errC == 0) {
- hTp->flags |= TPDEC_CONFIG_FOUND;
- } else {
- err = TRANSPORTDEC_PARSE_ERROR;
- goto bail;
+ errC = hTp->callbacks.cbUpdateConfig(
+ hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode,
+ &configChanged);
+ if (errC == 0) {
+ hTp->flags |= TPDEC_CONFIG_FOUND;
+ } else {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ if (err == TRANSPORTDEC_OK) {
+ if ((i == 0) && configChanged) {
+ int errC;
+ errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData,
+ &hTp->asc[0]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
}
}
}
@@ -1109,9 +1511,10 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1:
- {
+ if (err == TRANSPORTDEC_OK) {
int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND;
- err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer], NULL, NULL, &fConfigFound, NULL);
+ err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer],
+ NULL, NULL, &fConfigFound, NULL);
if (fConfigFound) {
hTp->flags |= TPDEC_CONFIG_FOUND;
}
@@ -1138,12 +1541,29 @@ bail:
return err;
}
-INT transportDec_GetAuBitsRemaining( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
-{
+TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer,
+ CSAudioSpecificConfig *asc) {
+ TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+
+ if (hTp != NULL) {
+ *asc = hTp->asc[layer];
+ err = TRANSPORTDEC_OK;
+ } else {
+ err = TRANSPORTDEC_INVALID_PARAMETER;
+ }
+ return err;
+}
+
+INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
INT bits;
if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
- bits = hTp->auLength[layer] - (hTp->accessUnitAnchor[layer] - FDKgetValidBits(&hTp->bitStream[layer]));
+ bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]);
+ if (bits >= 0) {
+ bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits);
+ }
} else {
bits = FDKgetValidBits(&hTp->bitStream[layer]);
}
@@ -1151,23 +1571,55 @@ INT transportDec_GetAuBitsRemaining( const HANDLE_TRANSPORTDEC hTp, const UINT l
return bits;
}
-INT transportDec_GetAuBitsTotal( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
-{
+INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp,
+ const UINT layer) {
return hTp->auLength[layer];
}
-TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount ( INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp )
-{
+TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount(
+ INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) {
*pNAccessUnits = hTp->missingAccessUnits;
return TRANSPORTDEC_OK;
}
/* Inform the transportDec layer that reading of access unit has finished. */
-TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp)
-{
+TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) {
TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
+ switch (hTp->transportFmt) {
+ case TT_MP4_LOAS:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LATM_MCP1: {
+ HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
+ if (hTp->numberOfRawDataBlocks == 0) {
+ /* Read other data if available. */
+ if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) {
+ int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm);
+
+ if ((INT)FDKgetValidBits(hBs) >= otherDataLen) {
+ FDKpushFor(hBs, otherDataLen);
+ } else {
+ /* Do byte align at the end of AudioMuxElement. */
+ if (hTp->numberOfRawDataBlocks == 0) {
+ FDKbyteAlign(hBs, hTp->globalFramePos);
+ }
+ return TRANSPORTDEC_NOT_ENOUGH_BITS;
+ }
+ }
+ } else {
+ /* If bit buffer has not more bits but hTp->numberOfRawDataBlocks > 0
+ then too many bits were read and obviously no more RawDataBlocks can
+ be read. Set numberOfRawDataBlocks to zero to attempt a new sync
+ attempt. */
+ if ((INT)FDKgetValidBits(hBs) <= 0) {
+ hTp->numberOfRawDataBlocks = 0;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
err = transportDec_AdjustEndOfAccessUnit(hTp);
@@ -1179,12 +1631,15 @@ TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp)
return err;
}
-TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp,
- const TPDEC_PARAM param,
- const INT value)
-{
+TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp,
+ const TPDEC_PARAM param,
+ const INT value) {
TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
+ if (hTp == NULL) {
+ return TRANSPORTDEC_INVALID_PARAMETER;
+ }
+
switch (param) {
case TPDEC_PARAM_MINIMIZE_DELAY:
if (value) {
@@ -1213,25 +1668,36 @@ TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp,
case TPDEC_PARAM_BURST_PERIOD:
hTp->burstPeriod = value;
break;
- case TPDEC_PARAM_RESET:
- {
- int i;
+ case TPDEC_PARAM_RESET: {
+ int i;
- for (i=0; i<(1*2); i++) {
- FDKresetBitbuffer(&hTp->bitStream[i]);
- hTp->auLength[i] = 0;
- hTp->accessUnitAnchor[i] = 0;
- }
- hTp->flags &= ~(TPDEC_SYNCOK|TPDEC_LOST_FRAMES_PENDING);
- if (hTp->transportFmt != TT_MP4_ADIF) {
- hTp->flags &= ~TPDEC_CONFIG_FOUND;
- }
- hTp->remainder = 0;
- hTp->avgBitRate = 0;
- hTp->missingAccessUnits = 0;
- hTp->numberOfRawDataBlocks = 0;
- hTp->globalFramePos = 0;
- hTp->holdOffFrames = 0;
+ for (i = 0; i < (1 * 1); i++) {
+ FDKresetBitbuffer(&hTp->bitStream[i]);
+ hTp->auLength[i] = 0;
+ hTp->accessUnitAnchor[i] = 0;
+ }
+ hTp->flags &= ~(TPDEC_SYNCOK | TPDEC_LOST_FRAMES_PENDING);
+ if (hTp->transportFmt != TT_MP4_ADIF) {
+ hTp->flags &= ~TPDEC_CONFIG_FOUND;
+ }
+ hTp->remainder = 0;
+ hTp->avgBitRate = 0;
+ hTp->missingAccessUnits = 0;
+ hTp->numberOfRawDataBlocks = 0;
+ hTp->globalFramePos = 0;
+ hTp->holdOffFrames = 0;
+ } break;
+ case TPDEC_PARAM_TARGETLAYOUT:
+ hTp->targetLayout = value;
+ break;
+ case TPDEC_PARAM_FORCE_CONFIG_CHANGE:
+ hTp->ctrlCFGChange[value].forceCfgChange = TPDEC_FORCE_CONFIG_CHANGE;
+ break;
+ case TPDEC_PARAM_USE_ELEM_SKIPPING:
+ if (value) {
+ hTp->flags |= TPDEC_USE_ELEM_SKIPPING;
+ } else {
+ hTp->flags &= ~TPDEC_USE_ELEM_SKIPPING;
}
break;
}
@@ -1239,38 +1705,30 @@ TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp,
return error;
}
-UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp)
-{
+UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) {
UINT nSubFrames = 0;
- if (hTp == NULL)
- return 0;
+ if (hTp == NULL) return 0;
- if (hTp->transportFmt==TT_MP4_LATM_MCP1 || hTp->transportFmt==TT_MP4_LATM_MCP0 || hTp->transportFmt==TT_MP4_LOAS)
+ if (hTp->transportFmt == TT_MP4_LATM_MCP1 ||
+ hTp->transportFmt == TT_MP4_LATM_MCP0 || hTp->transportFmt == TT_MP4_LOAS)
nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
- else if (hTp->transportFmt==TT_MP4_ADTS)
+ else if (hTp->transportFmt == TT_MP4_ADTS)
nSubFrames = hTp->parser.adts.bs.num_raw_blocks;
return nSubFrames;
}
-void transportDec_Close(HANDLE_TRANSPORTDEC *phTp)
-{
- if (phTp != NULL)
- {
+void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) {
+ if (phTp != NULL) {
if (*phTp != NULL) {
- if ( ! TT_IS_PACKET((*phTp)->transportFmt) ) {
- FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
- }
- if (*phTp != NULL) {
- FreeRam_TransportDecoder(phTp);
- }
+ FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer);
+ FreeRam_TransportDecoder(phTp);
}
}
}
-TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info )
-{
+TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) {
int i;
if (info == NULL) {
@@ -1284,7 +1742,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info )
if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR;
info += i;
- info->module_id = FDK_TPDEC;
+ info->module_id = FDK_TPDEC;
#ifdef __ANDROID__
info->build_date = "";
info->build_time = "";
@@ -1292,63 +1750,64 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info )
info->build_date = __DATE__;
info->build_time = __TIME__;
#endif
- info->title = TP_LIB_TITLE;
- info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
+ info->title = TP_LIB_TITLE;
+ info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
LIB_VERSION_STRING(info);
- info->flags = 0
- | CAPF_ADIF
- | CAPF_ADTS
- | CAPF_LATM
- | CAPF_LOAS
- | CAPF_RAWPACKETS
- | CAPF_DRM
- ;
+ info->flags = 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS |
+ CAPF_RAWPACKETS | CAPF_DRM;
return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
}
-
-int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits)
-{
+int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) {
switch (pTp->transportFmt) {
- case TT_MP4_ADTS:
- return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
- case TT_DRM:
- return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
- default:
- return 0;
+ case TT_MP4_ADTS:
+ return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
+ case TT_DRM:
+ return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
+ default:
+ return -1;
}
}
-void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg)
-{
+void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) {
switch (pTp->transportFmt) {
- case TT_MP4_ADTS:
- adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
- break;
- case TT_DRM:
- drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
- break;
- default:
- break;
+ case TT_MP4_ADTS:
+ adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
+ break;
+ case TT_DRM:
+ drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
+ break;
+ default:
+ break;
}
}
-TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)
-{
+TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) {
switch (pTp->transportFmt) {
- case TT_MP4_ADTS:
- if ( (pTp->parser.adts.bs.num_raw_blocks > 0) && (pTp->parser.adts.bs.protection_absent == 0) )
- {
- HANDLE_FDK_BITSTREAM hBs = &pTp->bitStream[0];
-
- transportDec_AdjustEndOfAccessUnit(pTp);
- }
- return adtsRead_CrcCheck(&pTp->parser.adts);
- case TT_DRM:
- return drmRead_CrcCheck(&pTp->parser.drm);
- break;
- default:
- return TRANSPORTDEC_OK;
+ case TT_MP4_ADTS:
+ if ((pTp->parser.adts.bs.num_raw_blocks > 0) &&
+ (pTp->parser.adts.bs.protection_absent == 0)) {
+ transportDec_AdjustEndOfAccessUnit(pTp);
+ }
+ return adtsRead_CrcCheck(&pTp->parser.adts);
+ case TT_DRM:
+ return drmRead_CrcCheck(&pTp->parser.drm);
+ default:
+ return TRANSPORTDEC_OK;
}
}
+
+TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf,
+ const UINT length) {
+ CSAudioSpecificConfig asc;
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
+
+ FDKinitBitStream(hBs, conf, BUFSIZE_DUMMY_VALUE, length << 3, BS_READER);
+
+ TRANSPORTDEC_ERROR err =
+ DrmRawSdcAudioConfig_Parse(&asc, hBs, NULL, (UCHAR)AC_CM_ALLOC_MEM, 0);
+
+ return err;
+}
diff --git a/libMpegTPDec/src/version b/libMpegTPDec/src/version
deleted file mode 100644
index 75e22c9..0000000
--- a/libMpegTPDec/src/version
+++ /dev/null
@@ -1,13 +0,0 @@
-
-/* library info */
-#define TP_LIB_VL0 2
-#define TP_LIB_VL1 3
-#define TP_LIB_VL2 7
-#define TP_LIB_TITLE "MPEG Transport"
-#ifdef __ANDROID__
-#define TP_LIB_BUILD_DATE ""
-#define TP_LIB_BUILD_TIME ""
-#else
-#define TP_LIB_BUILD_DATE __DATE__
-#define TP_LIB_BUILD_TIME __TIME__
-#endif