diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2013-08-29 12:29:46 -0700 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2013-09-03 11:31:55 -0700 |
commit | dbf96806482b2c48de4ba1da9a03e2bb7516b8c2 (patch) | |
tree | 102531985954bb98d15bbf7dfe8495f33e8ed4ca /libAACenc | |
parent | 3aec97e388e29a1d03f0197b27b893bc6aaf8ac3 (diff) | |
download | fdk-aac-dbf96806482b2c48de4ba1da9a03e2bb7516b8c2.tar.gz fdk-aac-dbf96806482b2c48de4ba1da9a03e2bb7516b8c2.tar.bz2 fdk-aac-dbf96806482b2c48de4ba1da9a03e2bb7516b8c2.zip |
Encoder explicit signaling
* AAC-Encoder
- Revise explicit signaling method which is required for downsampled SBR.
The parameter is optional and default configuration is implicit signaling
for dualrate SBR as before. In case of downsampled SBR and HE-AAC explicit
signaling is configured as default.
Modified file(s):
documentation\aacEncoder.pdf
libAACenc\include\aacenc_lib.h
libAACenc\src\aacenc_lib.cpp
libMpegTPEnc\src\tpenc_asc.cpp
libMpegTPEnc\src\version
libSYS\include\FDK_audio.h
libSYS\src\genericStds.cpp
Bug 9428126
Change-Id: I35138140346f17384d109ee5829be9ea5bab80fc
Diffstat (limited to 'libAACenc')
-rw-r--r-- | libAACenc/include/aacenc_lib.h | 52 | ||||
-rw-r--r-- | libAACenc/src/aacenc_lib.cpp | 111 |
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; |