aboutsummaryrefslogtreecommitdiffstats
path: root/libAACenc/src/aacenc_lib.cpp
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2013-08-29 12:24:04 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2013-08-29 12:24:04 -0700
commit3aec97e388e29a1d03f0197b27b893bc6aaf8ac3 (patch)
tree0cbc01e83d71aec25704fd9a6dd80b339d06c27a /libAACenc/src/aacenc_lib.cpp
parent7ad97579f8ccb843afdb5b184c4b209253839fe3 (diff)
downloadfdk-aac-dabplus-3aec97e388e29a1d03f0197b27b893bc6aaf8ac3.tar.gz
fdk-aac-dabplus-3aec97e388e29a1d03f0197b27b893bc6aaf8ac3.tar.bz2
fdk-aac-dabplus-3aec97e388e29a1d03f0197b27b893bc6aaf8ac3.zip
Encoder downsampled SBR
* AAC-Encoder - Introduce optional AACENC_SBR_RATIO encoder API parameter to configure dualrate or downsampled SBR explicitely. ELD makes use of downsampled SBR in default configuration. Modified file(s): documentation\aacEncoder.pdf libAACenc\include\aacenc_lib.h libAACenc\src\aacenc.h libAACenc\src\aacenc_lib.cpp * SBR-Encoder - Implement downsampled SBR feature. - Revise sbr tuning parameter selection. Modified file(s): libSBRenc\include\sbr_encoder.h libSBRenc\src\bit_sbr.h libSBRenc\src\env_est.cpp libSBRenc\src\mh_det.cpp libSBRenc\src\nf_est.cpp libSBRenc\src\ps_main.cpp libSBRenc\src\sbr.h libSBRenc\src\sbr_def.h libSBRenc\src\sbr_encoder.cpp libSBRenc\src\sbr_rom.cpp libSBRenc\src\sbr_rom.h libSBRenc\src\sbrenc_freq_sca.cpp libSBRenc\src\sbrenc_freq_sca.h libSBRenc\src\ton_corr.cpp Bug 9428126 Change-Id: I731720a10829272acaaf70b84525df00a09ff3d2
Diffstat (limited to 'libAACenc/src/aacenc_lib.cpp')
-rw-r--r--libAACenc/src/aacenc_lib.cpp163
1 files changed, 107 insertions, 56 deletions
diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp
index 4d5984d..0db84e8 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 8
+#define AACENCODER_LIB_VL2 9
#define AACENCODER_LIB_TITLE "AAC Encoder"
#define AACENCODER_LIB_BUILD_DATE __DATE__
#define AACENCODER_LIB_BUILD_TIME __TIME__
@@ -118,7 +118,7 @@ amm-info@iis.fraunhofer.de
#define SBL(fl) (fl/8) /*!< Short block length (hardcoded to 8 short blocks per long block) */
#define BSLA(fl) (4*SBL(fl)+SBL(fl)/2) /*!< AAC block switching look-ahead */
#define DELAY_AAC(fl) (fl+BSLA(fl)) /*!< MDCT + blockswitching */
-#define DELAY_AACELD(fl) ( (fl) + ((fl)/2) ) /*!< ELD FB delay */
+#define DELAY_AACELD(fl) ((fl)/2) /*!< ELD FB delay (no framing delay included) */
#define INPUTBUFFER_SIZE (1537+100+2048)
@@ -166,7 +166,8 @@ typedef struct {
UCHAR userMetaDataMode; /*!< Meta data library configuration. */
- UCHAR userSbrEnabled;
+ UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */
+ UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */
} USER_PARAM;
@@ -229,7 +230,7 @@ struct AACENCODER
UINT encoder_modis;
- /* Capabity flags */
+ /* Capability flags */
UINT CAPF_tpEnc;
} ;
@@ -255,6 +256,20 @@ static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig)
return ( sbrUsed );
}
+static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType)
+{
+ INT psUsed = 0;
+
+ if ( (audioObjectType==AOT_PS)
+ || (audioObjectType==AOT_MP2_PS)
+ || (audioObjectType==AOT_DABPLUS_PS)
+ || (audioObjectType==AOT_DRM_MPEG_PS) )
+ {
+ psUsed = 1;
+ }
+
+ return ( psUsed );
+}
/****************************************************************************
Allocate Encoder
****************************************************************************/
@@ -449,6 +464,14 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
config->userAncDataRate = 0;
+ /* SBR rate is set to 0 here, which means it should be set automatically
+ in FDKaacEnc_AdjustEncSettings() if the user did not set a rate
+ expilicitely. */
+ config->userSbrRatio = 0;
+
+ /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable configuration. */
+ config->userSbrEnabled = -1;
+
return AAC_ENC_OK;
}
@@ -483,6 +506,7 @@ INT aacEncoder_LimitBitrate(
INT bitRate,
const INT nSubFrames,
const INT sbrActive,
+ const INT sbrDownSampleRate,
const AUDIO_OBJECT_TYPE aot
)
{
@@ -492,8 +516,7 @@ INT aacEncoder_LimitBitrate(
FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm);
if (sbrActive) {
- /* Assume SBR rate ratio of 2:1 */
- coreSamplingRate = samplingRate / 2;
+ coreSamplingRate = samplingRate >> (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate-1):1);
} else {
coreSamplingRate = samplingRate;
}
@@ -669,19 +692,6 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
break;
}
- /* We need the frame length to call aacEncoder_LimitBitrate() */
- hAacConfig->bitRate = aacEncoder_LimitBitrate(
- NULL,
- hAacConfig->sampleRate,
- hAacConfig->framelength,
- hAacConfig->nChannels,
- hAacConfig->channelMode,
- config->userBitrate,
- hAacConfig->nSubFrames,
- isSbrActive(hAacConfig),
- hAacConfig->audioObjectType
- );
-
switch ( hAacConfig->audioObjectType ) {
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
@@ -699,24 +709,7 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
break;
}
- if (hAacConfig->epConfig >= 0) {
- hAacConfig->syntaxFlags |= AC_ER;
- if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) {
- return AACENC_INVALID_CONFIG; /* Cannel config 0 not supported. */
- }
- }
-
- if ( FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, hAacConfig->nChannels) != AAC_ENC_OK) {
- return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is just a check-up */
- }
-
- if ( (hAacConfig->nChannels > hAacEncoder->nMaxAacChannels)
- || ( (FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
- isSbrActive(hAacConfig) )
- )
- {
- return AACENC_INVALID_CONFIG; /* not enough channels allocated */
- }
+ hAacConfig->bitRate = config->userBitrate;
/* get bitrate in VBR configuration */
if ( (hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5) ) {
@@ -727,25 +720,52 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
/* Set default bitrate if no external bitrate declared. */
- if (hAacConfig->bitRate==-1) {
+ if ( (hAacConfig->bitrateMode==0) && (config->userBitrate==(UINT)-1) ) {
INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff * hAacConfig->sampleRate;
- switch (hAacConfig->audioObjectType)
+
+ if ( isPsActive(hAacConfig->audioObjectType) ) {
+ hAacConfig->bitRate = (bitrate>>1); /* 0.5 bit per sample */
+ }
+ else if ( isSbrActive(hAacConfig) )
+ {
+ if ( (config->userSbrRatio==2) || ((config->userSbrRatio==0)&&(hAacConfig->audioObjectType!=AOT_ER_AAC_ELD)) ) {
+ hAacConfig->bitRate = (bitrate + (bitrate>>2))>>1; /* 0.625 bits per sample */
+ }
+ if ( (config->userSbrRatio==1) || ((config->userSbrRatio==0)&&(hAacConfig->audioObjectType==AOT_ER_AAC_ELD)) ) {
+ hAacConfig->bitRate = (bitrate + (bitrate>>3)); /* 1.125 bits per sample */
+ }
+ } else
{
- case AOT_AAC_LC:
hAacConfig->bitRate = bitrate + (bitrate>>1); /* 1.5 bits per sample */
- break;
- case AOT_SBR:
- hAacConfig->bitRate = (bitrate + (bitrate>>2))>>1; /* 0.625 bits per sample */
- break;
- case AOT_PS:
- hAacConfig->bitRate = (bitrate>>1); /* 0.5 bit per sample */
- break;
- default:
- hAacConfig->bitRate = bitrate;
- break;
}
}
+ /* Initialize SBR parameters */
+ if ( (config->userSbrRatio==0) && (isSbrActive(hAacConfig)) ) {
+ /* Automatic SBR ratio configuration
+ * - downsampled SBR for ELD
+ * - otherwise always dualrate SBR
+ */
+ hAacConfig->sbrRatio = (hAacConfig->audioObjectType==AOT_ER_AAC_ELD) ? 1 : 2;
+ }
+ else {
+ /* SBR ratio has been set by the user, so use it. */
+ hAacConfig->sbrRatio = config->userSbrRatio;
+ }
+ /* We need the frame length to call aacEncoder_LimitBitrate() */
+ hAacConfig->bitRate = aacEncoder_LimitBitrate(
+ NULL,
+ hAacConfig->sampleRate,
+ hAacConfig->framelength,
+ hAacConfig->nChannels,
+ hAacConfig->channelMode,
+ hAacConfig->bitRate,
+ hAacConfig->nSubFrames,
+ isSbrActive(hAacConfig),
+ hAacConfig->sbrRatio,
+ hAacConfig->audioObjectType
+ );
+
/* Configure PNS */
if ( ((hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5)) /* VBR without PNS. */
|| (hAacConfig->useTns == 0) ) /* TNS required. */
@@ -753,6 +773,25 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
hAacConfig->usePns = 0;
}
+ if (hAacConfig->epConfig >= 0) {
+ hAacConfig->syntaxFlags |= AC_ER;
+ if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) {
+ return AACENC_INVALID_CONFIG; /* Cannel config 0 not supported. */
+ }
+ }
+
+ if ( FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, hAacConfig->nChannels) != AAC_ENC_OK) {
+ return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is just a check-up */
+ }
+
+ if ( (hAacConfig->nChannels > hAacEncoder->nMaxAacChannels)
+ || ( (FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff > hAacEncoder->nMaxSbrChannels) &&
+ isSbrActive(hAacConfig) )
+ )
+ {
+ return AACENC_INVALID_CONFIG; /* not enough channels allocated */
+ }
+
/* Meta data restriction. */
switch (hAacConfig->audioObjectType)
{
@@ -846,8 +885,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
SBR_ELEMENT_INFO sbrElInfo[(6)];
CHANNEL_MAPPING channelMapping;
- AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType;
-
if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode,
hAacConfig->channelOrder,
&channelMapping) != AAC_ENC_OK )
@@ -875,8 +912,9 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
&aacBufferOffset,
&hAacConfig->nChannels,
&hAacConfig->sampleRate,
+ &hAacConfig->sbrRatio,
&frameLength,
- &hAacConfig->audioObjectType,
+ hAacConfig->audioObjectType,
&hAacEncoder->nDelay,
(hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC,
(config->userTpHeaderPeriod!=0xFF) ? config->userTpHeaderPeriod : DEFAULT_HEADER_PERIOD_REPETITION_RATE,
@@ -884,7 +922,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
);
/* Suppress AOT reconfiguration and check error status. */
- if ( sbrError || (hAacConfig->audioObjectType!=aot) ) {
+ if (sbrError) {
return AACENC_INIT_SBR_ERROR;
}
@@ -953,7 +991,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
INT inputDataDelay = DELAY_AAC(hAacConfig->framelength);
if ( isSbrActive(hAacConfig) && hSbrEncoder!=NULL) {
- inputDataDelay = 2*inputDataDelay + sbrEncoder_GetInputDataDelay(*hSbrEncoder);
+ inputDataDelay = hAacConfig->sbrRatio*inputDataDelay + sbrEncoder_GetInputDataDelay(*hSbrEncoder);
}
if ( FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc,
@@ -1684,6 +1722,16 @@ AACENC_ERROR aacEncoder_SetParam(
}
}
break;
+ case AACENC_SBR_RATIO:
+ if (settings->userSbrRatio != value) {
+ if (! ((value==0) || (value==1) || (value==2)) ) {
+ err = AACENC_INVALID_CONFIG;
+ break;
+ }
+ settings->userSbrRatio = value;
+ hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT;
+ }
+ break;
case AACENC_SBR_MODE:
if (settings->userSbrEnabled != value) {
settings->userSbrEnabled = value;
@@ -1805,7 +1853,7 @@ UINT aacEncoder_GetParam(
value = (UINT)hAacEncoder->aacConfig.bitrateMode;
break;
case AACENC_SAMPLERATE:
- value = (UINT)settings->userSamplerate;
+ value = (UINT)hAacEncoder->coderConfig.extSamplingRate;
break;
case AACENC_CHANNELMODE:
value = (UINT)hAacEncoder->aacConfig.channelMode;
@@ -1822,6 +1870,9 @@ UINT aacEncoder_GetParam(
case AACENC_GRANULE_LENGTH:
value = (UINT)hAacEncoder->aacConfig.framelength;
break;
+ case AACENC_SBR_RATIO:
+ value = isSbrActive(&hAacEncoder->aacConfig) ? hAacEncoder->aacConfig.sbrRatio : 0;
+ break;
case AACENC_SBR_MODE:
value = (UINT) (hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0;
break;