summaryrefslogtreecommitdiffstats
path: root/libAACenc
diff options
context:
space:
mode:
Diffstat (limited to 'libAACenc')
-rw-r--r--libAACenc/include/aacenc_lib.h52
-rw-r--r--libAACenc/src/aacenc_lib.cpp111
2 files changed, 141 insertions, 22 deletions
diff --git a/libAACenc/include/aacenc_lib.h b/libAACenc/include/aacenc_lib.h
index 6002366..fcdaca5 100644
--- a/libAACenc/include/aacenc_lib.h
+++ b/libAACenc/include/aacenc_lib.h
@@ -938,14 +938,50 @@ typedef enum
- n: Frame count period. */
AACENC_SIGNALING_MODE = 0x0302, /*!< Signaling mode of the extension AOT:
- - 0: Implicit backward compatible signaling. (default)
- - 1: Explicit SBR and implicit PS signaling.
- - 2: Explicit hierarchical signaling.
-
- The use of backward-compatible implicit signaling is recommended if the user specically
- aims at preserving compatibility with decoders only capable of decoding AAC-LC. Otherwise
- use non-backward-compatible explicit signaling.
- Bitstream formats ADTS and ADIF can only do implicit signaling. */
+ - 0: Implicit backward compatible signaling (default for non-MPEG-4 based
+ AOT's and for the transport formats ADIF and ADTS)
+ - A stream that uses implicit signaling can be decoded by every AAC decoder, even AAC-LC-only decoders
+ - An AAC-LC-only decoder will only decode the low-frequency part of the stream, resulting in a band-limited output
+ - This method works with all transport formats
+ - This method does not work with downsampled SBR
+ - 1: Explicit backward compatible signaling
+ - A stream that uses explicit backward compatible signaling can be decoded by every AAC decoder, even AAC-LC-only decoders
+ - An AAC-LC-only decoder will only decode the low-frequency part of the stream, resulting in a band-limited output
+ - A decoder not capable of decoding PS will only decode the AAC-LC+SBR part.
+ If the stream contained PS, the result will be a a decoded mono downmix
+ - This method does not work with ADIF or ADTS. For LOAS/LATM, it only works with AudioMuxVersion==1
+ - This method does work with downsampled SBR
+ - 2: Explicit hierarchical signaling (default for MPEG-4 based AOT's and for all transport formats excluding ADIF and ADTS)
+ - A stream that uses explicit hierarchical signaling can be decoded only by HE-AAC decoders
+ - An AAC-LC-only decoder will not decode a stream that uses explicit hierarchical signaling
+ - A decoder not capable of decoding PS will not decode the stream at all if it contained PS
+ - This method does not work with ADIF or ADTS. It works with LOAS/LATM and the MPEG-4 File format
+ - This method does work with downsampled SBR
+
+ For making sure that the listener always experiences the best audio quality,
+ explicit hierarchical signaling should be used.
+ This makes sure that only a full HE-AAC-capable decoder will decode those streams.
+ The audio is played at full bandwidth.
+ For best backwards compatibility, it is recommended to encode with implicit SBR signaling.
+ A decoder capable of AAC-LC only will then only decode the AAC part, which means the decoded
+ audio will sound band-limited.
+
+ For MPEG-2 transport types (ADTS,ADIF), only implicit signaling is possible.
+
+ For LOAS and LATM, explicit backwards compatible signaling only works together with AudioMuxVersion==1.
+ The reason is that, for explicit backwards compatible signaling, additional information will be appended to the ASC.
+ A decoder that is only capable of decoding AAC-LC will skip this part.
+ Nevertheless, for jumping to the end of the ASC, it needs to know the ASC length.
+ Transmitting the length of the ASC is a feature of AudioMuxVersion==1, it is not possible to transmit the
+ length of the ASC with AudioMuxVersion==0, therefore an AAC-LC-only decoder will not be able to parse a
+ LOAS/LATM stream that was being encoded with AudioMuxVersion==0.
+
+ For downsampled SBR, explicit signaling is mandatory. The reason for this is that the
+ extension sampling frequency (which is in case of SBR the sampling frequqncy of the SBR part)
+ can only be signaled in explicit mode.
+
+ For AAC-ELD, the SBR information is transmitted in the ELDSpecific Config, which is part of the
+ AudioSpecificConfig. Therefore, the settings here will have no effect on AAC-ELD.*/
AACENC_TPSUBFRAMES = 0x0303, /*!< Number of sub frames in a transport frame for LOAS/LATM or ADTS (default 1).
- ADTS: Maximum number of sub frames restricted to 4.
diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp
index 0db84e8..8d32f3d 100644
--- a/libAACenc/src/aacenc_lib.cpp
+++ b/libAACenc/src/aacenc_lib.cpp
@@ -98,7 +98,7 @@ amm-info@iis.fraunhofer.de
/* Encoder library info */
#define AACENCODER_LIB_VL0 3
#define AACENCODER_LIB_VL1 4
-#define AACENCODER_LIB_VL2 9
+#define AACENCODER_LIB_VL2 10
#define AACENCODER_LIB_TITLE "AAC Encoder"
#define AACENCODER_LIB_BUILD_DATE __DATE__
#define AACENCODER_LIB_BUILD_TIME __TIME__
@@ -270,6 +270,56 @@ static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType)
return ( psUsed );
}
+
+static SBR_PS_SIGNALING getSbrSignalingMode(
+ const AUDIO_OBJECT_TYPE audioObjectType,
+ const TRANSPORT_TYPE transportType,
+ const UCHAR transportSignaling,
+ const UINT sbrRatio
+ )
+
+{
+ SBR_PS_SIGNALING sbrSignaling;
+
+ if (transportType==TT_UNKNOWN || sbrRatio==0) {
+ sbrSignaling = SIG_UNKNOWN; /* Needed parameters have not been set */
+ return sbrSignaling;
+ } else {
+ sbrSignaling = SIG_IMPLICIT; /* default: implicit signaling */
+ }
+
+ if ((audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) ||
+ (audioObjectType==AOT_MP2_AAC_LC) || (audioObjectType==AOT_MP2_SBR) || (audioObjectType==AOT_MP2_PS) ) {
+ switch (transportType) {
+ case TT_MP4_ADIF:
+ case TT_MP4_ADTS:
+ sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only implicit signaling is possible */
+ break;
+
+ case TT_MP4_RAW:
+ case TT_MP4_LATM_MCP1:
+ case TT_MP4_LATM_MCP0:
+ case TT_MP4_LOAS:
+ default:
+ if ( transportSignaling==0xFF ) {
+ /* Defaults */
+ if ( sbrRatio==1 ) {
+ sbrSignaling = SIG_EXPLICIT_HIERARCHICAL; /* For downsampled SBR, explicit signaling is mandatory */
+ } else {
+ sbrSignaling = SIG_IMPLICIT; /* For dual-rate SBR, implicit signaling is default */
+ }
+ } else {
+ /* User set parameters */
+ /* Attention: Backward compatible explicit signaling does only work with AMV1 for LATM/LOAS */
+ sbrSignaling = (SBR_PS_SIGNALING)transportSignaling;
+ }
+ break;
+ }
+ }
+
+ return sbrSignaling;
+}
+
/****************************************************************************
Allocate Encoder
****************************************************************************/
@@ -283,8 +333,12 @@ C_ALLOC_MEM (_AacEncoder, AACENCODER, 1)
/*
* Map Encoder specific config structures to CODER_CONFIG.
*/
-static
-void FDKaacEnc_MapConfig(CODER_CONFIG *cc, USER_PARAM *extCfg, HANDLE_AACENC_CONFIG hAacConfig)
+static void FDKaacEnc_MapConfig(
+ CODER_CONFIG *const cc,
+ const USER_PARAM *const extCfg,
+ const SBR_PS_SIGNALING sbrSignaling,
+ const HANDLE_AACENC_CONFIG hAacConfig
+ )
{
AUDIO_OBJECT_TYPE transport_AOT = AOT_NULL_OBJECT;
FDKmemclear(cc, sizeof(CODER_CONFIG));
@@ -321,17 +375,26 @@ void FDKaacEnc_MapConfig(CODER_CONFIG *cc, USER_PARAM *extCfg, HANDLE_AACENC_CON
}
/* Configure extension aot. */
- if (extCfg->userTpSignaling==0) {
+ if (sbrSignaling==SIG_IMPLICIT) {
cc->extAOT = AOT_NULL_OBJECT; /* implicit */
}
else {
- if ( (extCfg->userTpSignaling==1) && ( (transport_AOT==AOT_SBR) || (transport_AOT==AOT_PS) ) ) {
+ if ( (sbrSignaling==SIG_EXPLICIT_BW_COMPATIBLE) && ( (transport_AOT==AOT_SBR) || (transport_AOT==AOT_PS) ) ) {
cc->extAOT = AOT_SBR; /* explicit backward compatible */
}
else {
cc->extAOT = transport_AOT; /* explicit hierarchical */
}
}
+
+ if ( (transport_AOT==AOT_SBR) || (transport_AOT==AOT_PS) ) {
+ cc->sbrPresent=1;
+ if (transport_AOT==AOT_PS) {
+ cc->psPresent=1;
+ }
+ }
+ cc->sbrSignaling = sbrSignaling;
+
cc->extSamplingRate = extCfg->userSamplerate;
cc->bitRate = hAacConfig->bitRate;
cc->noChannels = hAacConfig->nChannels;
@@ -368,7 +431,6 @@ void FDKaacEnc_MapConfig(CODER_CONFIG *cc, USER_PARAM *extCfg, HANDLE_AACENC_CON
case AOT_MP2_SBR:
case AOT_MP2_PS:
cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */
- //config->userTpSignaling=0;
cc->extAOT = AOT_NULL_OBJECT;
break;
default:
@@ -428,7 +490,7 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
/* make reasonable default settings */
FDKaacEnc_AacInitDefaultConfig (hAacConfig);
- /* clear confure structure and copy default settings */
+ /* clear configuration structure and copy default settings */
FDKmemclear(config, sizeof(USER_PARAM));
/* copy encoder configuration settings */
@@ -455,7 +517,7 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
/* initialize transport parameters */
config->userTpType = TT_UNKNOWN;
config->userTpAmxv = 0;
- config->userTpSignaling = 0; /* default, implicit signaling */
+ config->userTpSignaling = 0xFF; /* choose signaling automatically */
config->userTpNsubFrames = 1;
config->userTpProtection = 0; /* not crc protected*/
config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */
@@ -651,9 +713,6 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
case AOT_MP2_SBR:
case AOT_MP2_PS:
hAacConfig->usePns = 0;
- if (config->userTpSignaling!=0) {
- return AACENC_INVALID_CONFIG; /* only implicit signaling allowed */
- }
case AOT_AAC_LC:
case AOT_SBR:
case AOT_PS:
@@ -681,7 +740,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0);
hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0);
hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0);
- hAacConfig->syntaxFlags |= ((config->userSbrEnabled) ? AC_SBR_PRESENT : 0);
+ hAacConfig->syntaxFlags |= ((config->userSbrEnabled==1) ? AC_SBR_PRESENT : 0);
config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS;
hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 512;
if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) {
@@ -752,6 +811,26 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
/* SBR ratio has been set by the user, so use it. */
hAacConfig->sbrRatio = config->userSbrRatio;
}
+
+ {
+ UCHAR tpSignaling=getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, config->userTpSignaling, hAacConfig->sbrRatio);
+
+ if ( (hAacConfig->audioObjectType==AOT_AAC_LC || hAacConfig->audioObjectType==AOT_SBR || hAacConfig->audioObjectType==AOT_PS) &&
+ (config->userTpType==TT_MP4_LATM_MCP1 || config->userTpType==TT_MP4_LATM_MCP0 || config->userTpType==TT_MP4_LOAS) &&
+ (tpSignaling==1) && (config->userTpAmxv==0) ) {
+ /* For backward compatible explicit signaling, AMV1 has to be active */
+ return AACENC_INVALID_CONFIG;
+ }
+
+ if ( (hAacConfig->audioObjectType==AOT_AAC_LC || hAacConfig->audioObjectType==AOT_SBR || hAacConfig->audioObjectType==AOT_PS) &&
+ (tpSignaling==0) && (hAacConfig->sbrRatio==1)) {
+ /* Downsampled SBR has to be signaled explicitely (for transmission of SBR sampling fequency) */
+ return AACENC_INVALID_CONFIG;
+ }
+ }
+
+
+
/* We need the frame length to call aacEncoder_LimitBitrate() */
hAacConfig->bitRate = aacEncoder_LimitBitrate(
NULL,
@@ -948,7 +1027,11 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
{
UINT flags = 0;
- FDKaacEnc_MapConfig(&hAacEncoder->coderConfig, config, hAacConfig);
+ FDKaacEnc_MapConfig(
+ &hAacEncoder->coderConfig,
+ config,
+ getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, config->userTpSignaling, hAacConfig->sbrRatio),
+ hAacConfig);
/* create flags for transport encoder */
if (config->userTpAmxv == 1) {
@@ -1880,7 +1963,7 @@ UINT aacEncoder_GetParam(
value = (UINT)settings->userTpType;
break;
case AACENC_SIGNALING_MODE:
- value = (UINT)settings->userTpSignaling;
+ value = (UINT)getSbrSignalingMode(hAacEncoder->aacConfig.audioObjectType, settings->userTpType, settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio);
break;
case AACENC_PROTECTION:
value = (UINT)settings->userTpProtection;