Commit 698b536f authored by Dave Burke's avatar Dave Burke

Update to 2012_05_11 version.

Fixes:
- Don't throw error for invalid bitrate but limit to functional value
- More robust ASC parsing
- More robust handling of corrupt bitstreams
- Handle multiple raw access units

Change-Id: Ib49fe2545ff4185fe924126da702fe84ac5c2d87
parent 9bf37cc9
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#define DRC_PARAMETER_BITS ( 7 ) #define DRC_PARAMETER_BITS ( 7 )
#define DRC_MAX_QUANT_STEPS ( 1<<DRC_PARAMETER_BITS ) #define DRC_MAX_QUANT_STEPS ( 1<<DRC_PARAMETER_BITS )
#define DRC_MAX_QUANT_FACTOR ( DRC_MAX_QUANT_STEPS-1 ) #define DRC_MAX_QUANT_FACTOR ( DRC_MAX_QUANT_STEPS-1 )
#define DRC_PARAM_QUANT_STEP ( FL2FXCONST_DBL(1.0f/(float)DRC_MAX_QUANT_STEPS) ) #define DRC_PARAM_QUANT_STEP ( FL2FXCONST_DBL(1.0f/(float)DRC_MAX_QUANT_FACTOR) )
#define DRC_PARAM_SCALE ( 1 ) #define DRC_PARAM_SCALE ( 1 )
#define MAX_REFERENCE_LEVEL ( 127 ) #define MAX_REFERENCE_LEVEL ( 127 )
...@@ -99,6 +99,7 @@ void aacDecoder_drcInitChannelData ( ...@@ -99,6 +99,7 @@ void aacDecoder_drcInitChannelData (
pDrcChData->bandTop[0] = (1024 >> 2) - 1; pDrcChData->bandTop[0] = (1024 >> 2) - 1;
pDrcChData->drcValue[0] = 0; pDrcChData->drcValue[0] = 0;
pDrcChData->drcInterpolationScheme = 0; pDrcChData->drcInterpolationScheme = 0;
pDrcChData->drcDataType = UNKNOWN_PAYLOAD;
} }
} }
...@@ -130,7 +131,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -130,7 +131,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
if (self == NULL) { if (self == NULL) {
return AAC_DEC_INVALID_HANDLE; return AAC_DEC_INVALID_HANDLE;
} }
self->params.cut = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)(value+1)); self->params.cut = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)value);
break; break;
case DRC_BOOST_SCALE: case DRC_BOOST_SCALE:
/* set boost factor */ /* set boost factor */
...@@ -141,7 +142,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -141,7 +142,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
if (self == NULL) { if (self == NULL) {
return AAC_DEC_INVALID_HANDLE; return AAC_DEC_INVALID_HANDLE;
} }
self->params.boost = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)(value+1)); self->params.boost = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)value);
break; break;
case TARGET_REF_LEVEL: case TARGET_REF_LEVEL:
if ( value > MAX_REFERENCE_LEVEL if ( value > MAX_REFERENCE_LEVEL
...@@ -300,14 +301,13 @@ int aacDecoder_drcMarkPayload ( ...@@ -300,14 +301,13 @@ int aacDecoder_drcMarkPayload (
break; break;
case DVB_DRC_ANC_DATA: case DVB_DRC_ANC_DATA:
bitCnt += 8;
/* check sync word */ /* check sync word */
if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE)
{ {
int dmxLevelsPresent, compressionPresent; int dmxLevelsPresent, compressionPresent;
int coarseGrainTcPresent, fineGrainTcPresent; int coarseGrainTcPresent, fineGrainTcPresent;
bitCnt+=8;
/* bs_info field */ /* bs_info field */
FDKreadBits(bs, 8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */ FDKreadBits(bs, 8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */
bitCnt+=8; bitCnt+=8;
...@@ -432,7 +432,7 @@ static int aacDecoder_drcParse ( ...@@ -432,7 +432,7 @@ static int aacDecoder_drcParse (
} }
/* Set DRC payload type */ /* Set DRC payload type */
pDrcBs->type = MPEG_DRC_EXT_DATA; pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA;
return (bitCnt); return (bitCnt);
} }
...@@ -515,23 +515,26 @@ static int aacDecoder_drcReadCompression ( ...@@ -515,23 +515,26 @@ static int aacDecoder_drcReadCompression (
if ( compressionOn ) { if ( compressionOn ) {
/* A compression value is available so store the data just like MPEG DRC data */ /* A compression value is available so store the data just like MPEG DRC data */
pDrcBs->channelData.drcValue[0] = compressionValue; pDrcBs->channelData.numBands = 1; /* One band ... */
pDrcBs->channelData.numBands = 1; /* one value for all bands */ pDrcBs->channelData.drcValue[0] = compressionValue; /* ... with one value ... */
pDrcBs->pceInstanceTag = -1; /* not present */ pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */
pDrcBs->progRefLevel = -1; /* not present */ pDrcBs->pceInstanceTag = -1; /* Not present */
pDrcBs->progRefLevel = -1; /* Not present */
pDrcBs->channelData.drcDataType = DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
} else { } else {
/* No compression value available */ /* No compression value available */
/* CAUTION: It is not clearly defined by standard how to react in this situation. */ /* CAUTION: It is not clearly defined by standard how to react in this situation. */
pDrcBs->channelData.drcValue[0] = 0x7F; /* 0dB */ /* Turn down the compression value to aprox. 0dB */
pDrcBs->channelData.bandTop[0] = 0; pDrcBs->channelData.numBands = 1; /* One band ... */
pDrcBs->channelData.drcValue[0] = 0x80; /* ... with aprox. 0dB ... */
pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */
pDrcBs->channelData.drcDataType = DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
/* If compression_on field is set to "0" the compression_value field shall be "0000 0000". */ /* If compression_on field is set to "0" the compression_value field shall be "0000 0000". */
if (compressionValue != 0) { if (compressionValue != 0) {
return 0; return 0;
} }
} }
/* Set DRC payload type now because the payload seems to be correct. */
pDrcBs->type = DVB_DRC_ANC_DATA;
} }
/* Read timecodes if available just to get the right amount of bits. */ /* Read timecodes if available just to get the right amount of bits. */
...@@ -617,7 +620,7 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -617,7 +620,7 @@ static int aacDecoder_drcExtractAndMap (
CDrcPayload *pThreadBs = &threadBs[thread]; CDrcPayload *pThreadBs = &threadBs[thread];
int numExclChns = 0; int numExclChns = 0;
switch (pThreadBs->type) { switch ((AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType) {
default: default:
continue; continue;
case MPEG_DRC_EXT_DATA: case MPEG_DRC_EXT_DATA:
...@@ -659,7 +662,7 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -659,7 +662,7 @@ static int aacDecoder_drcExtractAndMap (
/* thread applies to this channel */ /* thread applies to this channel */
if ( (pThreadBs->type == MPEG_DRC_EXT_DATA) if ( (pThreadBs->channelData.drcDataType == MPEG_DRC_EXT_DATA)
&& ( (numExcludedChns[thread] == 0) && ( (numExcludedChns[thread] == 0)
|| (!(pThreadBs->excludedChnsMask & (1<<ch))) ) ) { || (!(pThreadBs->excludedChnsMask & (1<<ch))) ) ) {
present++; present++;
...@@ -678,6 +681,7 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -678,6 +681,7 @@ static int aacDecoder_drcExtractAndMap (
{ {
CDrcPayload *pThreadBs = validThreadBs[thread]; CDrcPayload *pThreadBs = validThreadBs[thread];
INT exclMask = pThreadBs->excludedChnsMask; INT exclMask = pThreadBs->excludedChnsMask;
AACDEC_DRC_PAYLOAD_TYPE drcPayloadType = (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType;
int ch; int ch;
/* last progRefLevel transmitted is the one that is used /* last progRefLevel transmitted is the one that is used
...@@ -692,9 +696,9 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -692,9 +696,9 @@ static int aacDecoder_drcExtractAndMap (
int mapedChannel = channelMapping[ch]; int mapedChannel = channelMapping[ch];
if ( ((exclMask & (1<<mapedChannel)) == 0) if ( ((exclMask & (1<<mapedChannel)) == 0)
&& ( ( self->params.applyHeavyCompression && (pThreadBs->type == DVB_DRC_ANC_DATA)) && ( (drcPayloadType == MPEG_DRC_EXT_DATA)
|| (!self->params.applyHeavyCompression && (pThreadBs->type == MPEG_DRC_EXT_DATA)) ) || ((drcPayloadType == DVB_DRC_ANC_DATA) && self->params.applyHeavyCompression)
) { ) ) {
/* copy thread to channel */ /* copy thread to channel */
pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData; pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData;
} }
...@@ -781,10 +785,17 @@ void aacDecoder_drcApply ( ...@@ -781,10 +785,17 @@ void aacDecoder_drcApply (
UCHAR drcVal = pDrcChData->drcValue[band]; UCHAR drcVal = pDrcChData->drcValue[band];
top = fixMin((int)( (pDrcChData->bandTop[band]+1)<<2 ), aacFrameSize); top = fixMin((int)( (pDrcChData->bandTop[band]+1)<<2 ), aacFrameSize);
if ( pParams->applyHeavyCompression ) { fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
fact_exponent[band] = 1;
if ( pParams->applyHeavyCompression
&& ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == DVB_DRC_ANC_DATA) )
{
INT compressionFactorVal_e; INT compressionFactorVal_e;
int valX = drcVal >> 4; int valX, valY;
int valY = drcVal & 0x0F;
valX = drcVal >> 4;
valY = drcVal & 0x0F;
/* calculate the unscaled heavy compression factor. /* calculate the unscaled heavy compression factor.
compressionFactor = 48.164 - 6.0206*valX - 0.4014*valY dB compressionFactor = 48.164 - 6.0206*valX - 0.4014*valY dB
...@@ -801,11 +812,8 @@ void aacDecoder_drcApply ( ...@@ -801,11 +812,8 @@ void aacDecoder_drcApply (
fact_exponent[band] = DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e; fact_exponent[band] = DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e;
} }
else {
fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
fact_exponent[band] = 1;
}
} else } else
if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == MPEG_DRC_EXT_DATA)
{ {
/* apply the scaled dynamic range control words to factor. /* apply the scaled dynamic range control words to factor.
* if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0 * if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0
...@@ -824,10 +832,6 @@ void aacDecoder_drcApply ( ...@@ -824,10 +832,6 @@ void aacDecoder_drcApply (
3+DRC_PARAM_SCALE, 3+DRC_PARAM_SCALE,
&fact_exponent[band] ); &fact_exponent[band] );
} }
else {
fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
fact_exponent[band] = 1;
}
} }
fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa); fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa);
......
...@@ -42,8 +42,8 @@ ...@@ -42,8 +42,8 @@
typedef enum typedef enum
{ {
UNKNOWN_PAYLOAD = 0, UNKNOWN_PAYLOAD = 0,
MPEG_DRC_EXT_DATA, MPEG_DRC_EXT_DATA = 1,
DVB_DRC_ANC_DATA DVB_DRC_ANC_DATA = 2
} AACDEC_DRC_PAYLOAD_TYPE; } AACDEC_DRC_PAYLOAD_TYPE;
...@@ -54,12 +54,12 @@ typedef struct ...@@ -54,12 +54,12 @@ typedef struct
USHORT bandTop[MAX_DRC_BANDS]; USHORT bandTop[MAX_DRC_BANDS];
SHORT drcInterpolationScheme; SHORT drcInterpolationScheme;
UCHAR drcValue[MAX_DRC_BANDS]; UCHAR drcValue[MAX_DRC_BANDS];
SCHAR drcDataType;
} CDrcChannelData; } CDrcChannelData;
typedef struct typedef struct
{ {
AACDEC_DRC_PAYLOAD_TYPE type;
UINT excludedChnsMask; UINT excludedChnsMask;
SCHAR progRefLevel; SCHAR progRefLevel;
SCHAR pceInstanceTag; SCHAR pceInstanceTag;
......
...@@ -736,6 +736,9 @@ UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) ...@@ -736,6 +736,9 @@ UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr)
/* search for a line (which was decoded in previous state) which is not zero. [This value will get a sign] */ /* search for a line (which was decoded in previous state) which is not zero. [This value will get a sign] */
while ( pResultBase[iQSC] == (FIXP_DBL)0 ) { while ( pResultBase[iQSC] == (FIXP_DBL)0 ) {
iQSC++; /* points to current value different from zero */ iQSC++; /* points to current value different from zero */
if (iQSC >= 1024) {
return BODY_SIGN__SIGN;
}
} }
/* put sign together with line; if carryBit is zero, the sign is ok already; no write operation necessary in this case */ /* put sign together with line; if carryBit is zero, the sign is ok already; no write operation necessary in this case */
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
enum enum
{ {
TNS_MAX_WINDOWS = 8, /* 8 */ TNS_MAX_WINDOWS = 8, /* 8 */
TNS_MAXIMUM_ORDER = 12, /* 12 for AAC-LC and AAC-SSR. Set to 20 for AAC-Main (AOT 1). Some broken encoders also do order 20 for AAC-LC :( */ TNS_MAXIMUM_ORDER = 20, /* 12 for AAC-LC and AAC-SSR. Set to 20 for AAC-Main (AOT 1). Some broken encoders also do order 20 for AAC-LC :( */
TNS_MAXIMUM_FILTERS = 3 TNS_MAXIMUM_FILTERS = 3
}; };
......
...@@ -345,6 +345,7 @@ static AAC_DECODER_ERROR CProgramConfigElement_Read ( ...@@ -345,6 +345,7 @@ static AAC_DECODER_ERROR CProgramConfigElement_Read (
HANDLE_FDK_BITSTREAM bs, HANDLE_FDK_BITSTREAM bs,
HANDLE_TRANSPORTDEC pTp, HANDLE_TRANSPORTDEC pTp,
CProgramConfig *pce, CProgramConfig *pce,
UINT channelConfig,
UINT alignAnchor ) UINT alignAnchor )
{ {
AAC_DECODER_ERROR error = AAC_DEC_OK; AAC_DECODER_ERROR error = AAC_DEC_OK;
...@@ -362,8 +363,15 @@ static AAC_DECODER_ERROR CProgramConfigElement_Read ( ...@@ -362,8 +363,15 @@ static AAC_DECODER_ERROR CProgramConfigElement_Read (
transportDec_CrcEndReg(pTp, crcReg); transportDec_CrcEndReg(pTp, crcReg);
if (!pce->isValid && tmpPce->NumChannels <= (6) && tmpPce->Profile == 1) { if ( CProgramConfig_IsValid(tmpPce)
/* store PCE data */ && ( (channelConfig == 6 && (tmpPce->NumChannels == 6))
|| (channelConfig == 5 && (tmpPce->NumChannels == 5))
|| (channelConfig == 0 && (tmpPce->NumChannels == pce->NumChannels)) )
&& (tmpPce->NumFrontChannelElements == 2)
&& (tmpPce->NumSideChannelElements == 0)
&& (tmpPce->NumBackChannelElements == 1)
&& (tmpPce->Profile == 1) )
{ /* Copy the complete PCE including metadata. */
FDKmemcpy(pce, tmpPce, sizeof(CProgramConfig)); FDKmemcpy(pce, tmpPce, sizeof(CProgramConfig));
} }
...@@ -411,29 +419,18 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, ...@@ -411,29 +419,18 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
INT readBits = aacDecoder_drcMarkPayload( self->hDrcInfo, hBs, MPEG_DRC_EXT_DATA ); INT readBits = aacDecoder_drcMarkPayload( self->hDrcInfo, hBs, MPEG_DRC_EXT_DATA );
if (readBits > *count) if (readBits > *count)
{ { /* Read too much. Something went wrong! */
FDKpushBack(hBs, readBits - *count);
error = AAC_DEC_PARSE_ERROR; error = AAC_DEC_PARSE_ERROR;
return error;
}
else
{
*count -= (readBits+7) & ~0x7;
} }
*count -= readBits;
} }
break; break;
case EXT_LDSAC_DATA:
case EXT_SAC_DATA:
/* Skip MPEG Surround Extension payload */
FDKpushFor(hBs, *count);
*count = 0;
break;
case EXT_SBR_DATA_CRC: case EXT_SBR_DATA_CRC:
crcFlag = 1; crcFlag = 1;
case EXT_SBR_DATA: case EXT_SBR_DATA:
{ if (IS_CHANNEL_ELEMENT(previous_element)) {
SBR_ERROR sbrError; SBR_ERROR sbrError;
CAacDecoder_SyncQmfMode(self); CAacDecoder_SyncQmfMode(self);
...@@ -479,6 +476,8 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, ...@@ -479,6 +476,8 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
self->frameOK = 0; self->frameOK = 0;
} }
} }
} else {
error = AAC_DEC_PARSE_ERROR;
} }
break; break;
...@@ -523,14 +522,16 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, ...@@ -523,14 +522,16 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
*count -= (dataElementLength<<3); *count -= (dataElementLength<<3);
} else { } else {
/* align = 0 */ /* align = 0 */
FDKpushFor(hBs, (*count)<<3); error = AAC_DEC_PARSE_ERROR;
*count = 0; goto bail;
} }
} }
break; break;
case EXT_DATA_LENGTH: case EXT_DATA_LENGTH:
{ if ( !fIsFillElement /* Makes no sens to have an additional length in a fill ... */
&& (self->flags & AC_ER) ) /* ... element because this extension payload type was ... */
{ /* ... created to circumvent the missing length in ER-Syntax. */
int bitCnt, len = FDKreadBits(hBs, 4); int bitCnt, len = FDKreadBits(hBs, 4);
*count -= 4; *count -= 4;
...@@ -551,7 +552,9 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, ...@@ -551,7 +552,9 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
/* Check NOTE 2: The extension_payload() included here must /* Check NOTE 2: The extension_payload() included here must
not have extension_type == EXT_DATA_LENGTH. */ not have extension_type == EXT_DATA_LENGTH. */
error = AAC_DEC_PARSE_ERROR; error = AAC_DEC_PARSE_ERROR;
} else { goto bail;
}
else {
/* rewind and call myself again. */ /* rewind and call myself again. */
FDKpushBack(hBs, 4); FDKpushBack(hBs, 4);
...@@ -562,12 +565,13 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, ...@@ -562,12 +565,13 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
&bitCnt, &bitCnt,
previous_element, previous_element,
elIndex, elIndex,
0 ); 1 ); /* Treat same as fill element */
*count -= len - bitCnt; *count -= len - bitCnt;
} }
} /* Note: the fall through in case the if statement above is not taken is intentional. */
break; break;
}
case EXT_FIL: case EXT_FIL:
...@@ -578,6 +582,16 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, ...@@ -578,6 +582,16 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
break; break;
} }
bail:
if ( (error != AAC_DEC_OK)
&& fIsFillElement )
{ /* Skip the remaining extension bytes */
FDKpushBiDirectional(hBs, *count);
*count = 0;
/* Patch error code because decoding can go on. */
error = AAC_DEC_OK;
/* Be sure that parsing errors have been stored. */
}
return error; return error;
} }
...@@ -750,7 +764,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS ...@@ -750,7 +764,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
/* valid number of channels -> copy program config element (PCE) from ASC */ /* valid number of channels -> copy program config element (PCE) from ASC */
FDKmemcpy(&self->pce, &asc->m_progrConfigElement, sizeof(CProgramConfig)); FDKmemcpy(&self->pce, &asc->m_progrConfigElement, sizeof(CProgramConfig));
/* Built element table */ /* Built element table */
el = CProgramConfig_GetElementTable(&asc->m_progrConfigElement, self->elements); el = CProgramConfig_GetElementTable(&asc->m_progrConfigElement, self->elements, 7);
for (; el<7; el++) { for (; el<7; el++) {
self->elements[el] = ID_NONE; self->elements[el] = ID_NONE;
} }
...@@ -1286,7 +1300,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1286,7 +1300,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
} }
} }
#if defined(PCM_POSTPROCESS_ENABLE) && defined(DVB_MIXDOWN_ENABLE) && defined(AACDEC_DVB_SUPPORT_ENABLE)
{ {
UCHAR *pDvbAncData = NULL; UCHAR *pDvbAncData = NULL;
AAC_DECODER_ERROR ancErr; AAC_DECODER_ERROR ancErr;
...@@ -1309,7 +1322,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1309,7 +1322,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
0 /* not mpeg2 */ ); 0 /* not mpeg2 */ );
} }
} }
#endif /* PCM_POSTPROCESS_ENABLE && DVB_MIXDOWN_ENABLE && AACDEC_DVB_SUPPORT_ENABLE */
break; break;
#ifdef TP_PCE_ENABLE #ifdef TP_PCE_ENABLE
...@@ -1318,9 +1330,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1318,9 +1330,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
if ( CProgramConfigElement_Read( bs, if ( CProgramConfigElement_Read( bs,
self->hInput, self->hInput,
pce, pce,
self->streamInfo.channelConfig,
auStartAnchor ) ) auStartAnchor ) )
{ /* Built element table */ { /* Built element table */
int elIdx = CProgramConfig_GetElementTable(pce, self->elements); int elIdx = CProgramConfig_GetElementTable(pce, self->elements, 7);
/* Reset the remaining tabs */ /* Reset the remaining tabs */
for ( ; elIdx<7; elIdx++) { for ( ; elIdx<7; elIdx++) {
self->elements[elIdx] = ID_NONE; self->elements[elIdx] = ID_NONE;
...@@ -1368,7 +1381,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1368,7 +1381,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) ) if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) )
{ {
SBR_ERROR err; SBR_ERROR err = SBRDEC_OK;
int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE]; int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE];
for (elIdx = 0; elIdx < numChElements; elIdx += 1) for (elIdx = 0; elIdx < numChElements; elIdx += 1)
...@@ -1494,7 +1507,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1494,7 +1507,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Update number of output channels */ /* Update number of output channels */
self->streamInfo.numChannels = aacChannels; self->streamInfo.numChannels = aacChannels;
#if defined(TP_PCE_ENABLE) && defined(PCM_POSTPROCESS_ENABLE) && defined(MPEG_PCE_MIXDOWN_ENABLE) #ifdef TP_PCE_ENABLE
if (pceRead == 1 || CProgramConfig_IsValid(pce)) { if (pceRead == 1 || CProgramConfig_IsValid(pce)) {
/* Set matrix mixdown infos if available from PCE. */ /* Set matrix mixdown infos if available from PCE. */
pcmDmx_SetMatrixMixdownFromPce ( self->hPcmUtils, pcmDmx_SetMatrixMixdownFromPce ( self->hPcmUtils,
...@@ -1502,7 +1515,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( ...@@ -1502,7 +1515,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
pce->MatrixMixdownIndex, pce->MatrixMixdownIndex,
pce->PseudoSurroundEnable ); pce->PseudoSurroundEnable );
} }
#endif #endif
/* If there is no valid data to transfrom into time domain, return. */ /* If there is no valid data to transfrom into time domain, return. */
if ( ! IS_OUTPUT_VALID(ErrorStatus) ) { if ( ! IS_OUTPUT_VALID(ErrorStatus) ) {
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
/* Decoder library info */ /* Decoder library info */
#define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL0 2
#define AACDECODER_LIB_VL1 4 #define AACDECODER_LIB_VL1 4
#define AACDECODER_LIB_VL2 0 #define AACDECODER_LIB_VL2 1
#define AACDECODER_LIB_TITLE "AAC Decoder Lib" #define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#define AACDECODER_LIB_BUILD_DATE __DATE__ #define AACDECODER_LIB_BUILD_DATE __DATE__
#define AACDECODER_LIB_BUILD_TIME __TIME__ #define AACDECODER_LIB_BUILD_TIME __TIME__
...@@ -500,6 +500,8 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT ...@@ -500,6 +500,8 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT
return NULL; return NULL;
} }
transportDec_SetParam(pIn, TPDEC_PARAM_IGNORE_BUFFERFULLNESS, 1);
/* Allocate AAC decoder core struct. */ /* Allocate AAC decoder core struct. */
aacDec = CAacDecoder_Open(transportFmt); aacDec = CAacDecoder_Open(transportFmt);
......
...@@ -43,48 +43,61 @@ ...@@ -43,48 +43,61 @@
#define MIN_BUFSIZE_PER_EFF_CHAN 6144
static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate,
INT framelength, INT framelength,
INT ancillaryRate, INT ancillaryRate,
INT *ancillaryBitsPerFrame, INT *ancillaryBitsPerFrame,
INT sampleRate); INT sampleRate);
/** INT FDKaacEnc_LimitBitrate(
* For calculating average bitrate of an access unit 32 bit data width is not sufficient HANDLE_TRANSPORTENC hTpEnc,
* in worst case. Therefore use scaling of the samplingrate parameter to keep complete information. INT coreSamplingRate,
*/ INT frameLength,
typedef struct { INT nChannels,
INT samplingRate; INT nChannelsEff,
UCHAR scalingFactor; INT bitRate,
} SR_SCALING_TAB; INT averageBits,
INT *pAverageBitsPerFrame,
static const SR_SCALING_TAB samplingRateScalingTable[] = INT bitrateMode,
INT nSubFrames
)
{ {
{ 8000, 5 }, { 11025, 0 }, { 12000, 5 }, { 16000, 5 }, INT transportBits, prevBitRate, averageBitsPerFrame, shift = 0, iter=0;
{ 22050, 1 }, { 24000, 5 }, { 32000, 5 }, { 44100, 2 },
{ 48000, 5 }, { 64000, 5 }, { 88200, 3 }, { 96000, 5 }
};
/** while ( (frameLength & ~((1<<(shift+1))-1)) == frameLength
* Get maximal scaling factor without losing samplingrate accuracy. && (coreSamplingRate & ~((1<<(shift+1))-1)) == coreSamplingRate )
* {
* \param samplingRate Samplingrate to be used. shift ++;
* \return scaling value. }
*/
static int GetSrSf(const INT samplingRate)
{
int i, result = 0;
for (i=0; i<(int)(sizeof(samplingRateScalingTable)/sizeof(SR_SCALING_TAB)); i++) { do {
if ( samplingRateScalingTable[i].samplingRate == samplingRate ) { prevBitRate = bitRate;
result = samplingRateScalingTable[i].scalingFactor; averageBitsPerFrame = (bitRate*(frameLength>>shift)) / (coreSamplingRate>>shift) / nSubFrames;
break;
if (pAverageBitsPerFrame != NULL) {
*pAverageBitsPerFrame = averageBitsPerFrame;
} }
if (hTpEnc != NULL) {
transportBits = transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame);
} else {
/* Assume some worst case */
transportBits = 208;
} }
return result;
bitRate = FDKmax(bitRate, ((((40 * nChannels) + transportBits + frameLength) * (coreSamplingRate)) / frameLength) );
FDK_ASSERT(bitRate >= 0);
bitRate = FDKmin(bitRate, ((nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN)*(coreSamplingRate>>shift)) / (frameLength>>shift)) ;
FDK_ASSERT(bitRate >= 0);
} while (prevBitRate != bitRate && iter++ < 3) ;
return bitRate;
} }
#define MIN_BUFSIZE_PER_EFF_CHAN 6144
typedef struct typedef struct
{ {
...@@ -349,14 +362,18 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, ...@@ -349,14 +362,18 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc,
/* check bit rate */ /* check bit rate */
/* check if bitRate is not too low or high */ if (FDKaacEnc_LimitBitrate(
averageBitsPerFrame = (config->bitRate*(config->framelength>>GetSrSf(config->sampleRate))) / (config->sampleRate>>GetSrSf(config->sampleRate)) / config->nSubFrames; hTpEnc,
config->sampleRate,
/* assume minimum static bits of 40 in each channel. */ config->framelength,
if ( (averageBitsPerFrame <= ((40*config->nChannels) + transportEnc_GetStaticBits(hTpEnc, averageBitsPerFrame))) || config->nChannels,
( ((config->bitRate*(config->framelength>>GetSrSf(config->sampleRate)))) > FDKaacEnc_GetChannelModeConfiguration(config->channelMode)->nChannelsEff,
((FDKaacEnc_GetChannelModeConfiguration(config->channelMode)->nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN))*(config->sampleRate>>GetSrSf(config->sampleRate)) ) config->bitRate,
) config->averageBits,
&averageBitsPerFrame,
config->bitrateMode,
config->nSubFrames
) != config->bitRate )
{ {
return AAC_ENC_UNSUPPORTED_BITRATE; return AAC_ENC_UNSUPPORTED_BITRATE;
} }
......
...@@ -159,6 +159,33 @@ typedef struct { ...@@ -159,6 +159,33 @@ typedef struct {
typedef struct AAC_ENC *HANDLE_AAC_ENC; typedef struct AAC_ENC *HANDLE_AAC_ENC;
/**
* \brief Limit given bit rate to a valid value
* \param hTpEnc transport encoder handle
* \param coreSamplingRate the sample rate to be used for the AAC encoder
* \param frameLength the frameLength to be used for the AAC encoder
* \param nChannels number of total channels
* \param nChannelsEff number of effective channels
* \param bitRate the initial bit rate value for which the closest valid bit rate value is searched for
* \param averageBits average bits per frame for fixed framing. Set to -1 if not available.
* \param optional pointer where the current bits per frame are stored into.
* \param bitrateMode the current bit rate mode
* \param nSubFrames number of sub frames for super framing (not transport frames).
* \return a valid bit rate value as close as possible or identical to bitRate
*/
INT FDKaacEnc_LimitBitrate(
HANDLE_TRANSPORTENC hTpEnc,
INT coreSamplingRate,
INT frameLength,
INT nChannels,
INT nChannelsEff,
INT bitRate,
INT averageBits,
INT *pAverageBitsPerFrame,
INT bitrateMode,
INT nSubFrames
);
/*----------------------------------------------------------------------------- /*-----------------------------------------------------------------------------
functionname: FDKaacEnc_GetVBRBitrate functionname: FDKaacEnc_GetVBRBitrate
......
...@@ -388,6 +388,138 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig, ...@@ -388,6 +388,138 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig,
return AAC_ENC_OK; return AAC_ENC_OK;
} }
static
void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping, SBR_ELEMENT_INFO *sbrElInfo, INT bitRate)
{
INT codebits = bitRate;
int el;
/* Copy Element info */
for (el=0; el<channelMapping->nElements; el++) {
sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0];
sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1];
sbrElInfo[el].elType = channelMapping->elInfo[el].elType;
sbrElInfo[el].bitRate = (INT)(fMultNorm(channelMapping->elInfo[el].relativeBits, (FIXP_DBL)bitRate));
sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag;
sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl;
codebits -= sbrElInfo[el].bitRate;
}
sbrElInfo[0].bitRate += codebits;
}
static
INT aacEncoder_LimitBitrate(
const HANDLE_TRANSPORTENC hTpEnc,
const INT samplingRate,
const INT frameLength,
const INT nChannels,
const CHANNEL_MODE channelMode,
INT bitRate,
const INT nSubFrames,
const INT sbrActive,
const AUDIO_OBJECT_TYPE aot
)
{
INT coreSamplingRate;
CHANNEL_MAPPING cm;
FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm);
if (sbrActive) {
/* Assume SBR rate ratio of 2:1 */
coreSamplingRate = samplingRate / 2;
} else {
coreSamplingRate = samplingRate;
}
/* Consider bandwidth channel bit rate limit (see bandwidth.cpp: GetBandwidthEntry()) */
if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
bitRate = FDKmin(360000*nChannels, bitRate);
bitRate = FDKmax(8000*nChannels, bitRate);
}
if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
bitRate = FDKmin(576000*nChannels, bitRate);
/*bitRate = FDKmax(0*nChannels, bitRate);*/
}
/* Limit bit rate in respect to the core coder */
bitRate = FDKaacEnc_LimitBitrate(
hTpEnc,
coreSamplingRate,
frameLength,
nChannels,
cm.nChannelsEff,
bitRate,
-1,
NULL,
-1,
nSubFrames
);
/* Limit bit rate in respect to available SBR modes if active */
if (sbrActive)
{
SBR_ELEMENT_INFO sbrElInfo[6];
INT sbrBitRate = 0;
int e, tooBig=-1;
FDK_ASSERT(cm.nElements <= (6));
/* Get bit rate for each SBR element */
aacEncDistributeSbrBits(&cm, sbrElInfo, bitRate);
for (e=0; e<cm.nElements; e++)
{
INT sbrElementBitRateIn, sbrBitRateOut;
if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) {
continue;
}
sbrElementBitRateIn = sbrElInfo[e].bitRate;
sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn , cm.elInfo[e].nChannelsInEl, coreSamplingRate, aot);
if (sbrBitRateOut == 0) {
return 0;
}
if (sbrElementBitRateIn < sbrBitRateOut) {
FDK_ASSERT(tooBig != 1);
tooBig = 0;
if (e == 0) {
sbrBitRate = 0;
}
}
if (sbrElementBitRateIn > sbrBitRateOut) {
FDK_ASSERT(tooBig != 0);
tooBig = 1;
if (e == 0) {
sbrBitRate = 5000000;
}
}
if (tooBig != -1)
{
INT sbrBitRateLimit = (INT)fDivNorm((FIXP_DBL)sbrBitRateOut, cm.elInfo[e].relativeBits);
if (tooBig) {
sbrBitRate = fMin(sbrBitRate, sbrBitRateLimit-16);
FDK_ASSERT( (INT)fMultNorm(cm.elInfo[e].relativeBits, (FIXP_DBL)sbrBitRate) < sbrBitRateOut);
} else {
sbrBitRate = fMax(sbrBitRate, sbrBitRateLimit+16);
FDK_ASSERT( (INT)fMultNorm(cm.elInfo[e].relativeBits, (FIXP_DBL)sbrBitRate) >= sbrBitRateOut);
}
}
}
if (tooBig != -1) {
bitRate = sbrBitRate;
}
}
FDK_ASSERT(bitRate > 0);
return bitRate;
}
/* /*
* \brief Consistency check of given USER_PARAM struct and * \brief Consistency check of given USER_PARAM struct and
* copy back configuration from public struct into internal * copy back configuration from public struct into internal
...@@ -482,6 +614,19 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, ...@@ -482,6 +614,19 @@ AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder,
break; 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 ) { switch ( hAacConfig->audioObjectType ) {
case AOT_ER_AAC_LD: case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
...@@ -605,7 +750,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ...@@ -605,7 +750,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
INT frameLength = hAacConfig->framelength; INT frameLength = hAacConfig->framelength;
if ( (InitFlags & AACENC_INIT_CONFIG) ) if ( (InitFlags & AACENC_INIT_CONFIG) )
{ {
CHANNEL_MODE prevChMode = hAacConfig->channelMode; CHANNEL_MODE prevChMode = hAacConfig->channelMode;
...@@ -645,9 +789,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ...@@ -645,9 +789,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
INT sbrError; INT sbrError;
SBR_ELEMENT_INFO sbrElInfo[(6)]; SBR_ELEMENT_INFO sbrElInfo[(6)];
CHANNEL_MAPPING channelMapping; CHANNEL_MAPPING channelMapping;
int el;
INT codebits = hAacConfig->bitRate;
INT bitrateSc = CountLeadingBits(codebits);
AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType; AUDIO_OBJECT_TYPE aot = hAacConfig->audioObjectType;
if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode, if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode,
...@@ -662,19 +804,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ...@@ -662,19 +804,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder,
return AACENC_INIT_ERROR; return AACENC_INIT_ERROR;
} }
/* Copy Element info */ aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate);
for (el=0; el<channelMapping.nElements; el++) {
sbrElInfo[el].ChannelIndex[0] = channelMapping.elInfo[el].ChannelIndex[0];
sbrElInfo[el].ChannelIndex[1] = channelMapping.elInfo[el].ChannelIndex[1];
sbrElInfo[el].elType = channelMapping.elInfo[el].elType;
sbrElInfo[el].bitRate = (INT)(fMult(channelMapping.elInfo[el].relativeBits, (FIXP_DBL)(hAacConfig->bitRate<<bitrateSc))>>(bitrateSc));
sbrElInfo[el].instanceTag = channelMapping.elInfo[el].instanceTag;
sbrElInfo[el].nChannelsInEl = channelMapping.elInfo[el].nChannelsInEl;
sbrElInfo[el].bitRate = fMult(channelMapping.elInfo[el].relativeBits, (FIXP_DBL)hAacConfig->bitRate);
codebits -= sbrElInfo[el].bitRate;
}
sbrElInfo[0].bitRate += codebits;
UINT initFlag = 0; UINT initFlag = 0;
initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0; initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0;
......
...@@ -60,7 +60,7 @@ typedef shouldBeUnion{ ...@@ -60,7 +60,7 @@ typedef shouldBeUnion{
typedef struct{ typedef struct{
INT_PCM* psyInputBuffer; INT_PCM* psyInputBuffer;
FIXP_DBL RESTRICT overlapAddBuffer[1024]; FIXP_DBL overlapAddBuffer[1024];
BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */ BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */
FIXP_DBL sfbThresholdnm1[MAX_SFB]; /* FDKaacEnc_PreEchoControl */ FIXP_DBL sfbThresholdnm1[MAX_SFB]; /* FDKaacEnc_PreEchoControl */
......
...@@ -1314,23 +1314,30 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, ...@@ -1314,23 +1314,30 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm,
/* Now we can get the exact transport bit amount, and hopefully it is equal to the estimated value */ /* Now we can get the exact transport bit amount, and hopefully it is equal to the estimated value */
exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
while (exactTpBits != qcKernel->globHdrBits && (max_iter-- > 0)) if (exactTpBits != qcKernel->globHdrBits) {
{ INT diffFillBits = 0;
INT diffBits = qcKernel->globHdrBits-exactTpBits;
if (diffBits >= 0) { /* Number of bits which can be moved to bitreservoir. */
/* move bits from header to payload */ INT bitsToBitres = qcKernel->globHdrBits - exactTpBits;
qcOut->totFillBits += diffBits;
qcOut->totalBits += diffBits; if (bitsToBitres>0) {
qcOut->grantedDynBits += diffBits; /* if bitreservoir can not take all bits, move ramaining bits to fillbits */
diffFillBits = FDKmax(0, bitsToBitres - (qcKernel->bitResTotMax-qcKernel->bitResTot));
} }
else { else if (bitsToBitres<0) {
/* get missing bits from bitreservoir */ /* if bits mus be taken from bitreservoir, reduce fillbits first. */
qcKernel->bitResTot += diffBits; diffFillBits = (FDKmax(FDKmax(bitsToBitres, -qcKernel->bitResTot), -qcOut->totFillBits));
} }
qcKernel->globHdrBits = exactTpBits;
exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); diffFillBits = (diffFillBits+7)&~7; /* assure previous alignment */
qcOut->totFillBits += diffFillBits;
qcOut->totalBits += diffFillBits;
qcOut->grantedDynBits += diffFillBits;
/* new header bits */
qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits);
} }
FDK_ASSERT(exactTpBits == qcKernel->globHdrBits);
} }
/* Save total fill bits and distribut to alignment and fill bits */ /* Save total fill bits and distribut to alignment and fill bits */
......
/*************************** Fraunhofer IIS FDK Tools **********************
(C) Copyright Fraunhofer IIS (2011)
All Rights Reserved
Please be advised that this software and/or program delivery is
Confidential Information of Fraunhofer and subject to and covered by the
Fraunhofer IIS Software Evaluation Agreement
between Google Inc. and Fraunhofer
effective and in full force since March 1, 2012.
You may use this software and/or program only under the terms and
conditions described in the above mentioned Fraunhofer IIS Software
Evaluation Agreement. Any other and/or further use requires a separate agreement.
$Id$
Author(s): Markus Lohwasser
Description: FDK Tools Hybrid Filterbank
This software and/or program is protected by copyright law and international
treaties. Any reproduction or distribution of this software and/or program,
or any portion of it, may result in severe civil and criminal penalties, and
will be prosecuted to the maximum extent possible under law.
******************************************************************************/
#ifndef __FDK_HYBRID_H
#define __FDK_HYBRID_H
#include "common_fix.h"
/*--------------- enums -------------------------------*/
/**
* Hybrid Filterband modes.
*/
typedef enum {
THREE_TO_TEN,
THREE_TO_TWELVE,
THREE_TO_SIXTEEN
} FDK_HYBRID_MODE;
/*--------------- structure definitions ---------------*/
typedef struct FDK_HYBRID_SETUP *HANDLE_FDK_HYBRID_SETUP;
typedef struct
{
FIXP_DBL *bufferLFReal[3]; /*!< LF real filter states. */
FIXP_DBL *bufferLFImag[3]; /*!< LF imag filter states. */
FIXP_DBL *bufferHFReal[13]; /*!< HF real delay lines. */
FIXP_DBL *bufferHFImag[13]; /*!< HF imag delay lines. */
INT bufferLFpos; /*!< Position to write incoming data into ringbuffer. */
INT bufferHFpos; /*!< Delay line positioning. */
INT nrBands; /*!< Number of QMF bands. */
INT cplxBands; /*!< Number of complex QMF bands.*/
UCHAR hfMode; /*!< Flag signalizes treatment of HF bands. */
FIXP_DBL *pLFmemory; /*!< Pointer to LF states buffer. */
FIXP_DBL *pHFmemory; /*!< Pointer to HF states buffer. */
UINT LFmemorySize; /*!< Size of LF states buffer. */
UINT HFmemorySize; /*!< Size of HF states buffer. */
HANDLE_FDK_HYBRID_SETUP pSetup; /*!< Pointer to filter setup. */
} FDK_ANA_HYB_FILTER;
typedef struct
{
INT nrBands; /*!< Number of QMF bands. */
INT cplxBands; /*!< Number of complex QMF bands.*/
HANDLE_FDK_HYBRID_SETUP pSetup; /*!< Pointer to filter setup. */
} FDK_SYN_HYB_FILTER;
typedef FDK_ANA_HYB_FILTER *HANDLE_FDK_ANA_HYB_FILTER;
typedef FDK_SYN_HYB_FILTER *HANDLE_FDK_SYN_HYB_FILTER;
/**
* \brief Create one instance of Hybrid Analyis Filterbank.
*
* \param hAnalysisHybFilter Pointer to an outlying allocated Hybrid Analysis Filterbank structure.
* \param pLFmemory Pointer to outlying buffer used LF filtering.
* \param LFmemorySize Size of pLFmemory in bytes.
* \param pHFmemory Pointer to outlying buffer used HF delay line.
* \param HFmemorySize Size of pLFmemory in bytes.
*
* \return 0 on success.
*/
INT FDKhybridAnalysisOpen(
HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
FIXP_DBL *const pLFmemory,
const UINT LFmemorySize,
FIXP_DBL *const pHFmemory,
const UINT HFmemorySize
);
/**
* \brief Initialize and configure Hybrdid Analysis Filterbank instance.
*
* \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle.
* \param mode Select hybrid filter configuration.
* \param qmfBands Number of qmf bands to be processed.
* \param cplxBands Number of complex qmf bands to be processed.
* \param initStatesFlag Indicates whether the states buffer has to be cleared.
*
* \return 0 on success.
*/
INT FDKhybridAnalysisInit(
HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
const FDK_HYBRID_MODE mode,
const INT qmfBands,
const INT cplxBands,
const INT initStatesFlag
);
/**
* \brief Adjust Hybrdid Analysis Filterbank states.
*
* \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle.
* \param scalingValue Scaling value to be applied on filter states.
*
* \return 0 on success.
*/
INT FDKhybridAnalysisScaleStates(
HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
const INT scalingValue
);
/**
* \brief Apply Hybrid Analysis Filterbank on Qmf input data.
*
* \param hAnalysisHybFilter A Hybrid Analysis Filterbank handle.
* \param pQmfReal Qmf input data.
* \param pQmfImag Qmf input data.
* \param pHybridReal Hybrid output data.
* \param pHybridImag Hybrid output data.
*
* \return 0 on success.
*/
INT FDKhybridAnalysisApply(
HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter,
const FIXP_DBL *const pQmfReal,
const FIXP_DBL *const pQmfImag,
FIXP_DBL *const pHybridReal,
FIXP_DBL *const pHybridImag
);
/**
* \brief Close a Hybrid Analysis Filterbank instance.
*
* \param hAnalysisHybFilter Pointer to a Hybrid Analysis Filterbank instance.
*
* \return 0 on success.
*/
INT FDKhybridAnalysisClose(
HANDLE_FDK_ANA_HYB_FILTER hAnalysisHybFilter
);
/**
* \brief Initialize and configure Hybrdid Synthesis Filterbank instance.
*
* \param hSynthesisHybFilter A Hybrid Synthesis Filterbank handle.
* \param mode Select hybrid filter configuration.
* \param qmfBands Number of qmf bands to be processed.
* \param cplxBands Number of complex qmf bands to be processed.
*
* \return 0 on success.
*/
INT FDKhybridSynthesisInit(
HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
const FDK_HYBRID_MODE mode,
const INT qmfBands,
const INT cplxBands
);
/**
* \brief Apply Hybrid Analysis Filterbank on Hybrid data.
*
* \param hSynthesisHybFilter A Hybrid Analysis Filterbandk handle.
* \param pHybridReal Hybrid input data.
* \param pHybridImag Hybrid input data.
* \param pQmfReal Qmf output data.
* \param pQmfImag Qmf output data.
*
* \return 0 on success.
*/
INT FDKhybridSynthesisApply(
HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter,
const FIXP_DBL *const pHybridReal,
const FIXP_DBL *const pHybridImag,
FIXP_DBL *const pQmfReal,
FIXP_DBL *const pQmfImag
);
#endif /* __FDK_HYBRID_H */
...@@ -43,12 +43,12 @@ ...@@ -43,12 +43,12 @@
inline INT fixnorm_D(LONG value) inline INT fixnorm_D(LONG value)
{ {
INT result; INT result;
if (value < 0) {
value = ~value;
}
if (value == 0) { if (value == 0) {
return 0; return 0;
} }
if (value < 0) {
value = ~value;
}
result = fixnormz_D(value); result = fixnormz_D(value);
return result - 1; return result - 1;
} }
......
...@@ -206,6 +206,18 @@ FIXP_DBL fMultNorm( ...@@ -206,6 +206,18 @@ FIXP_DBL fMultNorm(
INT *result_e INT *result_e
); );
inline FIXP_DBL fMultNorm(FIXP_DBL f1, FIXP_DBL f2)
{
FIXP_DBL m;
INT e;
m = fMultNorm(f1, f2, &e);
m = scaleValueSaturate(m, e);
return m;
}
/** /**
* \brief Divide 2 FIXP_DBL values with normalization of input values. * \brief Divide 2 FIXP_DBL values with normalization of input values.
* \param num numerator * \param num numerator
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
*******************************************************************************/ *******************************************************************************/
/*! /*!
\file qmf.h \file qmf.h
\brief Complex qmf analysis/synthesis $Revision: 36871 $ \brief Complex qmf analysis/synthesis $Revision: 37444 $
\author Markus Werner \author Markus Werner
*/ */
......
...@@ -7,6 +7,7 @@ LOCAL_SRC_FILES := \ ...@@ -7,6 +7,7 @@ LOCAL_SRC_FILES := \
FDK_bitbuffer.cpp \ FDK_bitbuffer.cpp \
FDK_core.cpp \ FDK_core.cpp \
FDK_crc.cpp \ FDK_crc.cpp \
FDK_hybrid.cpp \
FDK_tools_rom.cpp \ FDK_tools_rom.cpp \
FDK_trigFcts.cpp \ FDK_trigFcts.cpp \
fft.cpp \ fft.cpp \
......
This diff is collapsed.
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
*******************************************************************************/ *******************************************************************************/
/*! /*!
\file dct.cpp \file dct.cpp
\brief DCT Implementations $Revision: 36871 $ \brief DCT Implementations $Revision: 37444 $
Library functions to calculate standard DCTs. This will most likely be replaced by hand-optimized Library functions to calculate standard DCTs. This will most likely be replaced by hand-optimized
functions for the specific target processor. functions for the specific target processor.
......
...@@ -344,7 +344,7 @@ static inline void fft15(FIXP_DBL *pInput) ...@@ -344,7 +344,7 @@ static inline void fft15(FIXP_DBL *pInput)
y[ 3 + iy] = ur - vi; /* Im B'= -Re C + Re D + Im A - Im B */ \ y[ 3 + iy] = ur - vi; /* Im B'= -Re C + Re D + Im A - Im B */ \
y[ 7 + iy] = vi + ur; /* Im D'= Re C - Re D + Im A - Im B */ y[ 7 + iy] = vi + ur; /* Im D'= Re C - Re D + Im A - Im B */
static const FIXP_SPK fft16_w16[2] = { {{STC(0x7641af3d), STC(0x30fbc54d)}}, {{ STC(0x30fbc54d), STC(0x7641af3d)}} }; static const FIXP_STP fft16_w16[2] = { STCP(0x7641af3d, 0x30fbc54d), STCP(0x30fbc54d, 0x7641af3d) };
LNK_SECTION_CODE_L1 LNK_SECTION_CODE_L1
inline void fft_16(FIXP_DBL *RESTRICT x) inline void fft_16(FIXP_DBL *RESTRICT x)
...@@ -527,10 +527,10 @@ inline void fft_16(FIXP_DBL *RESTRICT x) ...@@ -527,10 +527,10 @@ inline void fft_16(FIXP_DBL *RESTRICT x)
} }
#ifndef FUNCTION_fft_32 #ifndef FUNCTION_fft_32
static const FIXP_SPK fft32_w32[6] = static const FIXP_STP fft32_w32[6] =
{ {
{{ STC(0x7641af3d), STC(0x30fbc54d)}}, {{ STC(0x30fbc54d), STC(0x7641af3d)}}, {{ STC(0x7d8a5f40), STC(0x18f8b83c)}}, STCP (0x7641af3d, 0x30fbc54d), STCP(0x30fbc54d, 0x7641af3d), STCP(0x7d8a5f40, 0x18f8b83c),
{{ STC(0x6a6d98a4), STC(0x471cece7)}}, {{ STC(0x471cece7), STC(0x6a6d98a4)}}, {{ STC(0x18f8b83c), STC(0x7d8a5f40)}} STCP (0x6a6d98a4, 0x471cece7), STCP(0x471cece7, 0x6a6d98a4), STCP(0x18f8b83c, 0x7d8a5f40)
}; };
LNK_SECTION_CODE_L1 LNK_SECTION_CODE_L1
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
******************************************************************************/ ******************************************************************************/
/*! /*!
\file \file
\brief Complex qmf analysis/synthesis, $Revision: 36871 $ \brief Complex qmf analysis/synthesis, $Revision: 37444 $
This module contains the qmf filterbank for analysis [ cplxAnalysisQmfFiltering() ] and This module contains the qmf filterbank for analysis [ cplxAnalysisQmfFiltering() ] and
synthesis [ cplxSynthesisQmfFiltering() ]. It is a polyphase implementation of a complex synthesis [ cplxSynthesisQmfFiltering() ]. It is a polyphase implementation of a complex
exponential modulated filter bank. The analysis part usually runs at half the sample rate exponential modulated filter bank. The analysis part usually runs at half the sample rate
......
...@@ -162,7 +162,8 @@ int CProgramConfig_LookupElement( ...@@ -162,7 +162,8 @@ int CProgramConfig_LookupElement(
* \return Total element count including all SCE, CPE and LFE. * \return Total element count including all SCE, CPE and LFE.
*/ */
int CProgramConfig_GetElementTable( const CProgramConfig *pPce, int CProgramConfig_GetElementTable( const CProgramConfig *pPce,
MP4_ELEMENT_ID table[] ); MP4_ELEMENT_ID table[],
const INT elListSize );
/** /**
* \brief Initialize a given AudioSpecificConfig structure. * \brief Initialize a given AudioSpecificConfig structure.
......
...@@ -382,11 +382,19 @@ int CProgramConfig_LookupElement( ...@@ -382,11 +382,19 @@ int CProgramConfig_LookupElement(
#ifdef TP_PCE_ENABLE #ifdef TP_PCE_ENABLE
int CProgramConfig_GetElementTable( int CProgramConfig_GetElementTable(
const CProgramConfig *pPce, const CProgramConfig *pPce,
MP4_ELEMENT_ID elList[] MP4_ELEMENT_ID elList[],
const INT elListSize
) )
{ {
int i, el = 0; int i, el = 0;
if ( elListSize
< pPce->NumFrontChannelElements + pPce->NumSideChannelElements + pPce->NumBackChannelElements + pPce->NumLfeChannelElements
)
{
return 0;
}
for (i=0; i < pPce->NumFrontChannelElements; i++) for (i=0; i < pPce->NumFrontChannelElements; i++)
{ {
elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE; elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE;
...@@ -619,94 +627,6 @@ bail: ...@@ -619,94 +627,6 @@ bail:
#endif /* TP_ELD_ENABLE */ #endif /* TP_ELD_ENABLE */
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);
bitsAvailable -= 1;
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);
bitsAvailable -= 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;
}
if (cb->cbSsc != NULL) {
cb->cbSsc(
cb->cbSscData,
bs,
self->m_aot,
self->m_samplingFrequency,
1,
sscLen
);
} else
FDKpushFor(bs, sscLen); /* Skip SSC to be able to read the next extension if there is one. */
bitsAvailable -= sscLen*8;
}
}
break;
default:
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
}
return TRANSPORTDEC_OK;
}
/* /*
* API Functions * API Functions
...@@ -857,9 +777,6 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( ...@@ -857,9 +777,6 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
break; break;
} }
if (fExplicitBackwardCompatible) {
ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb);
}
return (ErrorStatus); return (ErrorStatus);
} }
......
...@@ -315,9 +315,6 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, CLa ...@@ -315,9 +315,6 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, CLa
else { else {
ErrorStatus = TRANSPORTDEC_PARSE_ERROR; //AAC_DEC_LATM_TIMEFRAMING; ErrorStatus = TRANSPORTDEC_PARSE_ERROR; //AAC_DEC_LATM_TIMEFRAMING;
} }
if ((INT)FDKgetValidBits(bs) < totalPayloadBits) {
return TRANSPORTDEC_NOT_ENOUGH_BITS;
}
if (pLatmDemux->m_audioMuxLengthBytes > 0 && totalPayloadBits > pLatmDemux->m_audioMuxLengthBytes*8) { if (pLatmDemux->m_audioMuxLengthBytes > 0 && totalPayloadBits > pLatmDemux->m_audioMuxLengthBytes*8) {
return TRANSPORTDEC_PARSE_ERROR; return TRANSPORTDEC_PARSE_ERROR;
} }
......
...@@ -85,6 +85,7 @@ struct TRANSPORTDEC ...@@ -85,6 +85,7 @@ struct TRANSPORTDEC
#define TPDEC_IGNORE_BUFFERFULLNESS 4 #define TPDEC_IGNORE_BUFFERFULLNESS 4
#define TPDEC_EARLY_CONFIG 8 #define TPDEC_EARLY_CONFIG 8
#define TPDEC_LOST_FRAMES_PENDING 16 #define TPDEC_LOST_FRAMES_PENDING 16
#define TPDEC_CONFIG_FOUND 32
C_ALLOC_MEM(Ram_TransportDecoder, TRANSPORTDEC, 1) C_ALLOC_MEM(Ram_TransportDecoder, TRANSPORTDEC, 1)
C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, TRANSPORTDEC_INBUF_SIZE) C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, TRANSPORTDEC_INBUF_SIZE)
...@@ -177,11 +178,10 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR * ...@@ -177,11 +178,10 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *
} }
} }
break; break;
default:
case TT_MP4_RAW: case TT_MP4_RAW:
err = AudioSpecificConfig_Parse(&hTp->asc[layer], hBs, 1, &hTp->callbacks); err = AudioSpecificConfig_Parse(&hTp->asc[layer], hBs, 1, &hTp->callbacks);
break; break;
default:
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
} }
if (err == TRANSPORTDEC_OK) { if (err == TRANSPORTDEC_OK) {
int errC; int errC;
...@@ -192,6 +192,10 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR * ...@@ -192,6 +192,10 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *
} }
} }
if (err == TRANSPORTDEC_OK) {
hTp->flags |= TPDEC_CONFIG_FOUND;
}
return err; return err;
} }
...@@ -439,6 +443,14 @@ TRANSPORTDEC_ERROR synchronization( ...@@ -439,6 +443,14 @@ TRANSPORTDEC_ERROR synchronization(
totalBits = (INT)FDKgetValidBits(hBs); totalBits = (INT)FDKgetValidBits(hBs);
if (totalBits <= 0) {
/* Return sync error, because this happens only in case of severly damaged bit streams.
Returning TRANSPORTDEC_NOT_ENOUGH_BITS here is very dangerous. */
/* numberOfRawDataBlocks must be always reset in case of sync errors. */
hTp->numberOfRawDataBlocks = 0;
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 */ /* Set transport specific sync parameters */
...@@ -625,7 +637,9 @@ TRANSPORTDEC_ERROR synchronization( ...@@ -625,7 +637,9 @@ TRANSPORTDEC_ERROR synchronization(
if (err == TRANSPORTDEC_SYNC_ERROR) { if (err == TRANSPORTDEC_SYNC_ERROR) {
int bits; int bits;
FDK_ASSERT(hTp->numberOfRawDataBlocks == 0); /* Enforce re-sync of transport headers. */
hTp->numberOfRawDataBlocks = 0;
/* Ensure that the bit amount lands and a multiple of TPDEC_SYNCSKIP */ /* Ensure that the bit amount lands and a multiple of TPDEC_SYNCSKIP */
bits = (bitsAvail + headerBits) % 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. */
...@@ -710,6 +724,7 @@ TRANSPORTDEC_ERROR synchronization( ...@@ -710,6 +724,7 @@ TRANSPORTDEC_ERROR synchronization(
err = TRANSPORTDEC_OK; err = TRANSPORTDEC_OK;
} }
bail:
hTp->auLength[0] = rawDataBlockLength; hTp->auLength[0] = rawDataBlockLength;
if (err == TRANSPORTDEC_OK) { if (err == TRANSPORTDEC_OK) {
...@@ -852,7 +867,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c ...@@ -852,7 +867,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
case TT_MP4_ADIF: case TT_MP4_ADIF:
/* Read header if not already done */ /* Read header if not already done */
if (!(hTp->flags & TPDEC_SYNCOK)) if (!(hTp->flags & TPDEC_CONFIG_FOUND))
{ {
CProgramConfig *pce; CProgramConfig *pce;
...@@ -876,8 +891,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c ...@@ -876,8 +891,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]); errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
if (errC == 0) { if (errC == 0) {
/* Misuse sync flag to parse header only once. */ hTp->flags |= TPDEC_CONFIG_FOUND;
hTp->flags |= TPDEC_SYNCOK;
} else { } else {
err = TRANSPORTDEC_PARSE_ERROR; err = TRANSPORTDEC_PARSE_ERROR;
goto bail; goto bail;
......
...@@ -33,15 +33,6 @@ ...@@ -33,15 +33,6 @@
#include "FDK_bitstream.h" #include "FDK_bitstream.h"
#include "genericStds.h" #include "genericStds.h"
#define ASC_FLAG_EXT 0x0001
#define ASC_FLAG_SBR 0x0002
#define ASC_FLAG_SBRCRC 0x0004
#define ASC_FLAG_VCB11 0x0010
#define ASC_FLAG_RVLC 0x0020
#define ASC_FLAG_HCR 0x0040
#define ASC_FLAG_HCR 0x0040
#define PCE_MAX_ELEMENTS 8 #define PCE_MAX_ELEMENTS 8
/** /**
...@@ -353,7 +344,6 @@ int transportEnc_writeELDSpecificConfig( ...@@ -353,7 +344,6 @@ int transportEnc_writeELDSpecificConfig(
HANDLE_FDK_BITSTREAM hBs, HANDLE_FDK_BITSTREAM hBs,
CODER_CONFIG *config, CODER_CONFIG *config,
int epConfig, int epConfig,
int flags,
CSTpCallBacks *cb CSTpCallBacks *cb
) )
{ {
...@@ -363,14 +353,14 @@ int transportEnc_writeELDSpecificConfig( ...@@ -363,14 +353,14 @@ int transportEnc_writeELDSpecificConfig(
} }
FDKwriteBits(hBs, (config->samplesPerFrame == 480) ? 1 : 0, 1); FDKwriteBits(hBs, (config->samplesPerFrame == 480) ? 1 : 0, 1);
FDKwriteBits(hBs, (flags & ASC_FLAG_VCB11) ? 1:0, 1); FDKwriteBits(hBs, (config->flags & CC_VCB11 ) ? 1:0, 1);
FDKwriteBits(hBs, (flags & ASC_FLAG_RVLC ) ? 1:0, 1); FDKwriteBits(hBs, (config->flags & CC_RVLC ) ? 1:0, 1);
FDKwriteBits(hBs, (flags & ASC_FLAG_HCR ) ? 1:0, 1); FDKwriteBits(hBs, (config->flags & CC_HCR ) ? 1:0, 1);
FDKwriteBits(hBs, (flags & ASC_FLAG_SBR) ? 1:0, 1); /* SBR header flag */ FDKwriteBits(hBs, (config->flags & CC_SBR) ? 1:0, 1); /* SBR header flag */
if ( (flags & ASC_FLAG_SBR) ) { if ( (config->flags & CC_SBR) ) {
FDKwriteBits(hBs, (config->samplingRate == config->extSamplingRate) ? 0:1, 1); /* Samplerate Flag */ FDKwriteBits(hBs, (config->samplingRate == config->extSamplingRate) ? 0:1, 1); /* Samplerate Flag */
FDKwriteBits(hBs, (flags &ASC_FLAG_SBRCRC) ? 1:0, 1); /* SBR CRC flag*/ FDKwriteBits(hBs, (config->flags & CC_SBRCRC) ? 1:0, 1); /* SBR CRC flag*/
if (cb->cbSbr != NULL) { if (cb->cbSbr != NULL) {
const PCE_CONFIGURATION *pPce; const PCE_CONFIGURATION *pPce;
...@@ -399,7 +389,7 @@ int transportEnc_writeASC ( ...@@ -399,7 +389,7 @@ int transportEnc_writeASC (
CSTpCallBacks *cb CSTpCallBacks *cb
) )
{ {
UINT flags = 0; UINT extFlag = 0;
int err; int err;
int epConfig = 0; int epConfig = 0;
...@@ -416,14 +406,11 @@ int transportEnc_writeASC ( ...@@ -416,14 +406,11 @@ int transportEnc_writeASC (
case AOT_ER_AAC_LD: case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
case AOT_USAC: case AOT_USAC:
flags |= ASC_FLAG_EXT; extFlag = 1;
break; break;
default: default:
break; break;
} }
if (config->flags & CC_SBR) {
flags |= ASC_FLAG_SBR;
}
if (config->extAOT == AOT_SBR || config->extAOT == AOT_PS) if (config->extAOT == AOT_SBR || config->extAOT == AOT_PS)
writeAot(asc, config->extAOT); writeAot(asc, config->extAOT);
...@@ -462,14 +449,14 @@ int transportEnc_writeASC ( ...@@ -462,14 +449,14 @@ int transportEnc_writeASC (
case AOT_ER_TWIN_VQ: case AOT_ER_TWIN_VQ:
case AOT_ER_BSAC: case AOT_ER_BSAC:
case AOT_ER_AAC_LD: case AOT_ER_AAC_LD:
err = transportEnc_writeGASpecificConfig(asc, config, (flags & ASC_FLAG_EXT) ? 1:0, alignAnchor); err = transportEnc_writeGASpecificConfig(asc, config, extFlag, alignAnchor);
if (err) if (err)
return err; return err;
break; break;
#endif /* TP_GA_ENABLE */ #endif /* TP_GA_ENABLE */
#ifdef TP_ELD_ENABLE #ifdef TP_ELD_ENABLE
case AOT_ER_AAC_ELD: case AOT_ER_AAC_ELD:
err = transportEnc_writeELDSpecificConfig(asc, config, epConfig, flags, cb); err = transportEnc_writeELDSpecificConfig(asc, config, epConfig, cb);
if (err) if (err)
return err; return err;
break; break;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
*******************************************************************************/ *******************************************************************************/
/*! /*!
\file \file
\brief Envelope extraction $Revision: 36841 $ \brief Envelope extraction $Revision: 38006 $
The functions provided by this module are mostly called by applySBR(). After it is The functions provided by this module are mostly called by applySBR(). After it is
determined that there is valid SBR data, sbrGetHeaderData() might be called if the current determined that there is valid SBR data, sbrGetHeaderData() might be called if the current
SBR data contains an \ref SBR_HEADER_ELEMENT as opposed to a \ref SBR_STANDARD_ELEMENT. This function SBR data contains an \ref SBR_HEADER_ELEMENT as opposed to a \ref SBR_STANDARD_ELEMENT. This function
...@@ -167,6 +167,10 @@ initHeaderData ( ...@@ -167,6 +167,10 @@ initHeaderData (
/* One SBR timeslot corresponds to the amount of samples equal to the amount of analysis bands, divided by the timestep. */ /* One SBR timeslot corresponds to the amount of samples equal to the amount of analysis bands, divided by the timestep. */
hHeaderData->numberTimeSlots = (samplesPerFrame/numAnalysisBands) >> (hHeaderData->timeStep - 1); hHeaderData->numberTimeSlots = (samplesPerFrame/numAnalysisBands) >> (hHeaderData->timeStep - 1);
if (hHeaderData->numberTimeSlots > (16)) {
sbrError = SBRDEC_UNSUPPORTED_CONFIG;
}
hHeaderData->numberOfAnalysisBands = numAnalysisBands; hHeaderData->numberOfAnalysisBands = numAnalysisBands;
bail: bail:
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
*******************************************************************************/ *******************************************************************************/
/*! /*!
\file \file
\brief Sbr decoder $Revision: 36841 $ \brief Sbr decoder $Revision: 37646 $
This module provides the actual decoder implementation. The SBR data (side information) is already This module provides the actual decoder implementation. The SBR data (side information) is already
decoded. Only three functions are provided: decoded. Only three functions are provided:
...@@ -537,6 +537,9 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ ...@@ -537,6 +537,9 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
maxShift = hSbrDec->sbrDrcChannel.nextFact_exp; maxShift = hSbrDec->sbrDrcChannel.nextFact_exp;
} }
/* copy DRC data to right channel (with PS both channels use the same DRC gains) */
FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel, sizeof(SBRDEC_DRC_CHANNEL));
for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */ for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */
INT outScalefactorR, outScalefactorL; INT outScalefactorR, outScalefactorL;
...@@ -565,7 +568,7 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ ...@@ -565,7 +568,7 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
sbrDecoder_drcApplySlot ( /* right channel */ sbrDecoder_drcApplySlot ( /* right channel */
&hSbrDec->sbrDrcChannel, &hSbrDecRight->sbrDrcChannel,
rQmfReal, rQmfReal,
rQmfImag, rQmfImag,
i, i,
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/*! /*!
\file \file
\brief Memory layout \brief Memory layout
$Revision: 36841 $ $Revision: 38012 $
This module declares all static and dynamic memory spaces This module declares all static and dynamic memory spaces
*/ */
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
*******************************************************************************/ *******************************************************************************/
/*! /*!
\file \file
\brief SBR decoder frontend $Revision: 36841 $ \brief SBR decoder frontend $Revision: 38029 $
This module provides a frontend to the SBR decoder. The function openSBR() is called for This module provides a frontend to the SBR decoder. The function openSBR() is called for
initialization. The function sbrDecoder_Apply() is called for each frame. sbr_Apply() will call the initialization. The function sbrDecoder_Apply() is called for each frame. sbr_Apply() will call the
required functions to decode the raw SBR data (provided by env_extr.cpp), to decode the envelope data and noise floor levels [decodeSbrData()], required functions to decode the raw SBR data (provided by env_extr.cpp), to decode the envelope data and noise floor levels [decodeSbrData()],
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
/* Decoder library info */ /* Decoder library info */
#define SBRDECODER_LIB_VL0 2 #define SBRDECODER_LIB_VL0 2
#define SBRDECODER_LIB_VL1 1 #define SBRDECODER_LIB_VL1 1
#define SBRDECODER_LIB_VL2 0 #define SBRDECODER_LIB_VL2 1
#define SBRDECODER_LIB_TITLE "SBR Decoder" #define SBRDECODER_LIB_TITLE "SBR Decoder"
#define SBRDECODER_LIB_BUILD_DATE __DATE__ #define SBRDECODER_LIB_BUILD_DATE __DATE__
#define SBRDECODER_LIB_BUILD_TIME __TIME__ #define SBRDECODER_LIB_BUILD_TIME __TIME__
...@@ -367,6 +367,7 @@ SBR_ERROR sbrDecoder_InitElement ( ...@@ -367,6 +367,7 @@ SBR_ERROR sbrDecoder_InitElement (
{ {
SBR_ERROR sbrError = SBRDEC_OK; SBR_ERROR sbrError = SBRDEC_OK;
int chCnt=0; int chCnt=0;
int nSbrElementsStart = self->numSbrElements;
/* Check core codec AOT */ /* Check core codec AOT */
if (! sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (4)) { if (! sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (4)) {
...@@ -488,8 +489,13 @@ SBR_ERROR sbrDecoder_InitElement ( ...@@ -488,8 +489,13 @@ SBR_ERROR sbrDecoder_InitElement (
bail: bail:
if (sbrError != SBRDEC_OK) { if (sbrError != SBRDEC_OK) {
if (nSbrElementsStart < self->numSbrElements) {
/* Free the memory allocated for this element */ /* Free the memory allocated for this element */
sbrDecoder_DestroyElement( self, elementIndex ); sbrDecoder_DestroyElement( self, elementIndex );
} else if (self->pSbrElement[elementIndex] != NULL) {
/* Set error flag to trigger concealment */
self->pSbrElement[elementIndex]->frameErrorFlag[self->pSbrElement[elementIndex]->useFrameSlot] = 1;;
}
} }
return sbrError; return sbrError;
...@@ -933,7 +939,8 @@ SBR_ERROR sbrDecoder_Parse( ...@@ -933,7 +939,8 @@ SBR_ERROR sbrDecoder_Parse(
1); 1);
} }
if (headerStatus == HEADER_RESET) { if (headerStatus == HEADER_RESET)
{
errorStatus = sbrDecoder_HeaderUpdate( errorStatus = sbrDecoder_HeaderUpdate(
self, self,
hSbrHeader, hSbrHeader,
...@@ -1130,6 +1137,10 @@ sbrDecoder_DecodeElement ( ...@@ -1130,6 +1137,10 @@ sbrDecoder_DecodeElement (
self->flags self->flags
); );
if (errorStatus != SBRDEC_OK) {
return errorStatus;
}
hSbrHeader->syncState = UPSAMPLING; hSbrHeader->syncState = UPSAMPLING;
errorStatus = sbrDecoder_HeaderUpdate( errorStatus = sbrDecoder_HeaderUpdate(
...@@ -1139,6 +1150,11 @@ sbrDecoder_DecodeElement ( ...@@ -1139,6 +1150,11 @@ sbrDecoder_DecodeElement (
pSbrChannel, pSbrChannel,
hSbrElement->nChannels hSbrElement->nChannels
); );
if (errorStatus != SBRDEC_OK) {
hSbrHeader->syncState = SBR_NOT_INITIALIZED;
return errorStatus;
}
} }
/* reset */ /* reset */
...@@ -1296,6 +1312,11 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self, ...@@ -1296,6 +1312,11 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
psPossible = *psDecoded; psPossible = *psDecoded;
if (self->numSbrElements < 1) {
/* exit immediately to avoid access violations */
return SBRDEC_CREATE_ERROR;
}
/* Sanity check of allocated SBR elements. */ /* Sanity check of allocated SBR elements. */
for (sbrElementNum=0; sbrElementNum<self->numSbrElements; sbrElementNum++) { for (sbrElementNum=0; sbrElementNum<self->numSbrElements; sbrElementNum++) {
if (self->pSbrElement[sbrElementNum] == NULL) { if (self->pSbrElement[sbrElementNum] == NULL) {
......
...@@ -212,6 +212,16 @@ INT sbrEncoder_Open( ...@@ -212,6 +212,16 @@ INT sbrEncoder_Open(
INT supportPS INT supportPS
); );
/**
* \brief get closest working bit rate to specified desired bit rate for a single SBR element
* \param bitRate the desired target bit rate
* \param numChannels the amount of audio channels
* \param coreSampleRate the sample rate of the core coder
* \param the current Audio Object Type
* \return closest working bit rate to bitRate value
*/
UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot);
/** /**
* \brief Initialize SBR Encoder instance. * \brief Initialize SBR Encoder instance.
* \param phSbrEncoder Pointer to a SBR Encoder instance. * \param phSbrEncoder Pointer to a SBR Encoder instance.
......
...@@ -16,7 +16,6 @@ LOCAL_SRC_FILES := \ ...@@ -16,7 +16,6 @@ LOCAL_SRC_FILES := \
env_est.cpp \ env_est.cpp \
invf_est.cpp \ invf_est.cpp \
nf_est.cpp \ nf_est.cpp \
psenc_hybrid.cpp \
ps_main.cpp \ ps_main.cpp \
sbrenc_freq_sca.cpp \ sbrenc_freq_sca.cpp \
sbr_misc.cpp \ sbr_misc.cpp \
......
...@@ -799,27 +799,6 @@ calculateSbrEnvelope (FIXP_DBL **RESTRICT YBufferLeft, /*! energy buffer left * ...@@ -799,27 +799,6 @@ calculateSbrEnvelope (FIXP_DBL **RESTRICT YBufferLeft, /*! energy buffer left *
} /* i*/ } /* i*/
} }
/*
* Update QMF buffers
*/
static void FDKsbrEnc_updateRIBuffers(HANDLE_ENV_CHANNEL h_envChan)
{
int i;
/* rBufferWriteOffset ist always 0, do we need this ? */
for (i = 0; i < h_envChan->sbrExtractEnvelope.rBufferWriteOffset; i++) {
FIXP_DBL *temp;
temp = h_envChan->sbrExtractEnvelope.rBuffer[i];
h_envChan->sbrExtractEnvelope.rBuffer[i] = h_envChan->sbrExtractEnvelope.rBuffer[i + h_envChan->sbrExtractEnvelope.no_cols];
h_envChan->sbrExtractEnvelope.rBuffer[i + h_envChan->sbrExtractEnvelope.no_cols] = temp;
temp = h_envChan->sbrExtractEnvelope.iBuffer[i];
h_envChan->sbrExtractEnvelope.iBuffer[i] = h_envChan->sbrExtractEnvelope.iBuffer[i + h_envChan->sbrExtractEnvelope.no_cols];
h_envChan->sbrExtractEnvelope.iBuffer[i + h_envChan->sbrExtractEnvelope.no_cols] = temp;
}
}
/***************************************************************************/ /***************************************************************************/
/*! /*!
...@@ -873,8 +852,8 @@ FDKsbrEnc_extractSbrEnvelope1 ( ...@@ -873,8 +852,8 @@ FDKsbrEnc_extractSbrEnvelope1 (
Precalculation of Tonality Quotas COEFF Transform OK Precalculation of Tonality Quotas COEFF Transform OK
*/ */
FDKsbrEnc_CalculateTonalityQuotas(&hEnvChan->TonCorr, FDKsbrEnc_CalculateTonalityQuotas(&hEnvChan->TonCorr,
sbrExtrEnv->rBuffer+ sbrExtrEnv->rBufferWriteOffset, sbrExtrEnv->rBuffer,
sbrExtrEnv->iBuffer+ sbrExtrEnv->rBufferWriteOffset, sbrExtrEnv->iBuffer,
h_con->freqBandTable[HI][h_con->nSfb[HI]], h_con->freqBandTable[HI][h_con->nSfb[HI]],
hEnvChan->qmfScale); hEnvChan->qmfScale);
...@@ -914,8 +893,6 @@ FDKsbrEnc_extractSbrEnvelope1 ( ...@@ -914,8 +893,6 @@ FDKsbrEnc_extractSbrEnvelope1 (
sbrExtrEnv->no_cols); sbrExtrEnv->no_cols);
FDKsbrEnc_updateRIBuffers(hEnvChan);
} }
/***************************************************************************/ /***************************************************************************/
...@@ -1741,12 +1718,11 @@ FDKsbrEnc_InitExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut, ...@@ -1741,12 +1718,11 @@ FDKsbrEnc_InitExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
{ {
hSbrCut->YBufferWriteOffset = tran_off*time_step; hSbrCut->YBufferWriteOffset = tran_off*time_step;
} }
hSbrCut->rBufferWriteOffset = 0;
hSbrCut->rBufferReadOffset = 0; hSbrCut->rBufferReadOffset = 0;
YBufferLength = hSbrCut->YBufferWriteOffset + no_cols; YBufferLength = hSbrCut->YBufferWriteOffset + no_cols;
rBufferLength = hSbrCut->rBufferWriteOffset + no_cols; rBufferLength = no_cols;
hSbrCut->pre_transient_info[0] = 0; hSbrCut->pre_transient_info[0] = 0;
hSbrCut->pre_transient_info[1] = 0; hSbrCut->pre_transient_info[1] = 0;
...@@ -1824,8 +1800,8 @@ FDKsbrEnc_deleteExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut) ...@@ -1824,8 +1800,8 @@ FDKsbrEnc_deleteExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut)
INT INT
FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr) FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr)
{ {
return hSbr->no_rows*((hSbr->YBufferWriteOffset)*2 + /* mult 2 because nrg's are grouped half */ return hSbr->no_rows*((hSbr->YBufferWriteOffset)*2 /* mult 2 because nrg's are grouped half */
hSbr->rBufferWriteOffset - hSbr->rBufferReadOffset ); /* in reference hold half spec and calc nrg's on overlapped spec */ - hSbr->rBufferReadOffset ); /* in reference hold half spec and calc nrg's on overlapped spec */
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
****************************************************************************/ ****************************************************************************/
/*! /*!
\file \file
\brief Envelope estimation structs and prototypes $Revision: 36847 $ \brief Envelope estimation structs and prototypes $Revision: 37142 $
*/ */
#ifndef __ENV_EST_H #ifndef __ENV_EST_H
#define __ENV_EST_H #define __ENV_EST_H
...@@ -56,7 +56,6 @@ typedef struct ...@@ -56,7 +56,6 @@ typedef struct
int YBufferWriteOffset; int YBufferWriteOffset;
int YBufferSzShift; int YBufferSzShift;
int rBufferReadOffset; int rBufferReadOffset;
int rBufferWriteOffset;
int no_cols; int no_cols;
int no_rows; int no_rows;
......
...@@ -202,8 +202,7 @@ static const UINT opdDeltaTime_Code[] = ...@@ -202,8 +202,7 @@ static const UINT opdDeltaTime_Code[] =
static const INT psBands[] = static const INT psBands[] =
{ {
PS_BANDS_COARSE, PS_BANDS_COARSE,
PS_BANDS_MID, PS_BANDS_MID
PS_BANDS_FINE
}; };
static INT getNoBands(PS_RESOLUTION mode) static INT getNoBands(PS_RESOLUTION mode)
......
...@@ -28,6 +28,17 @@ ...@@ -28,6 +28,17 @@
#ifndef PS_CONST_H #ifndef PS_CONST_H
#define PS_CONST_H #define PS_CONST_H
#define MAX_PS_CHANNELS ( 2 )
#define HYBRID_MAX_QMF_BANDS ( 3 )
#define HYBRID_FILTER_LENGTH ( 13 )
#define HYBRID_FILTER_DELAY ( (HYBRID_FILTER_LENGTH-1)/2 )
#define HYBRID_FRAMESIZE ( QMF_MAX_TIME_SLOTS )
#define HYBRID_READ_OFFSET ( 10 )
#define MAX_HYBRID_BANDS ( (QMF_CHANNELS-HYBRID_MAX_QMF_BANDS+10) )
typedef enum { typedef enum {
PS_RES_COARSE = 0, PS_RES_COARSE = 0,
PS_RES_MID = 1, PS_RES_MID = 1,
...@@ -37,8 +48,7 @@ typedef enum { ...@@ -37,8 +48,7 @@ typedef enum {
typedef enum { typedef enum {
PS_BANDS_COARSE = 10, PS_BANDS_COARSE = 10,
PS_BANDS_MID = 20, PS_BANDS_MID = 20,
PS_BANDS_FINE = 34, PS_MAX_BANDS = PS_BANDS_MID
PS_MAX_BANDS = PS_BANDS_FINE
} PS_BANDS; } PS_BANDS;
typedef enum { typedef enum {
...@@ -62,4 +72,14 @@ typedef enum { ...@@ -62,4 +72,14 @@ typedef enum {
} PS_CONSTS; } PS_CONSTS;
typedef enum {
PSENC_OK = 0x0000, /*!< No error happened. All fine. */
PSENC_INVALID_HANDLE = 0x0020, /*!< Handle passed to function call was invalid. */
PSENC_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */
PSENC_INIT_ERROR = 0x0040, /*!< General initialization error. */
PSENC_ENCODE_ERROR = 0x0060 /*!< The encoding process was interrupted by an unexpected error. */
} FDK_PSENC_ERROR;
#endif #endif
This diff is collapsed.
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
******************************************************************************/ ******************************************************************************/
/*! /*!
\file \file
\brief PS parameter extraction, encoding functions $Revision: 36847 $ \brief PS parameter extraction, encoding functions $Revision: 37142 $
*/ */
#ifndef __INCLUDED_PS_ENCODE_H #ifndef __INCLUDED_PS_ENCODE_H
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include "ps_const.h" #include "ps_const.h"
#include "ps_bitenc.h" #include "ps_bitenc.h"
#include "psenc_hybrid.h"
#define IID_SCALE_FT (64.f) /* maxVal in Quant tab is +/- 50 */ #define IID_SCALE_FT (64.f) /* maxVal in Quant tab is +/- 50 */
#define IID_SCALE 6 /* maxVal in Quant tab is +/- 50 */ #define IID_SCALE 6 /* maxVal in Quant tab is +/- 50 */
...@@ -81,7 +81,7 @@ typedef struct T_PS_DATA { ...@@ -81,7 +81,7 @@ typedef struct T_PS_DATA {
typedef struct T_PS_ENCODE{ typedef struct T_PS_ENCODE{
HANDLE_PS_DATA hPsData; PS_DATA psData;
PS_BANDS psEncMode; PS_BANDS psEncMode;
INT nQmfIidGroups; INT nQmfIidGroups;
...@@ -97,21 +97,29 @@ typedef struct T_PS_ENCODE{ ...@@ -97,21 +97,29 @@ typedef struct T_PS_ENCODE{
typedef struct T_PS_ENCODE *HANDLE_PS_ENCODE; typedef struct T_PS_ENCODE *HANDLE_PS_ENCODE;
typedef struct T_PS_CHANNEL_DATA *HANDLE_PS_CHANNEL_DATA;
HANDLE_ERROR_INFO FDKsbrEnc_CreatePSEncode(HANDLE_PS_ENCODE *phPsEncode);
HANDLE_ERROR_INFO FDKsbrEnc_InitPSEncode(HANDLE_PS_ENCODE hPsEncode, const PS_BANDS psEncMode, const FIXP_DBL iidQuantErrorThreshold); FDK_PSENC_ERROR FDKsbrEnc_CreatePSEncode(
HANDLE_PS_ENCODE *phPsEncode
);
HANDLE_ERROR_INFO FDKsbrEnc_DestroyPSEncode(HANDLE_PS_ENCODE *phPsEncode); FDK_PSENC_ERROR FDKsbrEnc_InitPSEncode(
HANDLE_PS_ENCODE hPsEncode,
const PS_BANDS psEncMode,
const FIXP_DBL iidQuantErrorThreshold
);
FDK_PSENC_ERROR FDKsbrEnc_DestroyPSEncode(
HANDLE_PS_ENCODE *phPsEncode
);
HANDLE_ERROR_INFO FDKsbrEnc_PSEncode(HANDLE_PS_ENCODE hPsEncode, FDK_PSENC_ERROR FDKsbrEnc_PSEncode(
HANDLE_PS_ENCODE hPsEncode,
HANDLE_PS_OUT hPsOut, HANDLE_PS_OUT hPsOut,
HANDLE_PS_CHANNEL_DATA hChanDatal,
HANDLE_PS_CHANNEL_DATA hChanDatar,
UCHAR *dynBandScale, UCHAR *dynBandScale,
UINT maxEnvelopes, UINT maxEnvelopes,
const int sendHeader); FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2],
const INT frameSize,
const INT sendHeader
);
#endif #endif
This diff is collapsed.
...@@ -30,16 +30,18 @@ ...@@ -30,16 +30,18 @@
/* Includes ******************************************************************/ /* Includes ******************************************************************/
#include "sbr_def.h" #include "sbr_def.h"
#include "psenc_hybrid.h" #include "qmf.h"
#include "ps_encode.h" #include "ps_encode.h"
#include "FDK_bitstream.h" #include "FDK_bitstream.h"
#include "FDK_hybrid.h"
/* Data Types ****************************************************************/ /* Data Types ****************************************************************/
typedef enum { typedef enum {
PSENC_STEREO_BANDS_INVALID = 0, PSENC_STEREO_BANDS_INVALID = 0,
PSENC_STEREO_BANDS_10 = 10, PSENC_STEREO_BANDS_10 = 10,
PSENC_STEREO_BANDS_20 = 20, PSENC_STEREO_BANDS_20 = 20
PSENC_STEREO_BANDS_34 = 34
} PSENC_STEREO_BANDS_CONFIG; } PSENC_STEREO_BANDS_CONFIG;
typedef enum { typedef enum {
...@@ -48,13 +50,10 @@ typedef enum { ...@@ -48,13 +50,10 @@ typedef enum {
PSENC_NENV_4 = 4, PSENC_NENV_4 = 4,
PSENC_NENV_DEFAULT = PSENC_NENV_2, PSENC_NENV_DEFAULT = PSENC_NENV_2,
PSENC_NENV_MAX = PSENC_NENV_4 PSENC_NENV_MAX = PSENC_NENV_4
} PSENC_NENV_CONFIG;
#define MAX_PS_CHANNELS ( 2 ) } PSENC_NENV_CONFIG;
#define PSENC_QMF_BUFFER_LENGTH ( 48 )
typedef struct { typedef struct {
UINT bitrateFrom; /* inclusive */ UINT bitrateFrom; /* inclusive */
UINT bitrateTo; /* exclusive */ UINT bitrateTo; /* exclusive */
PSENC_STEREO_BANDS_CONFIG nStereoBands; PSENC_STEREO_BANDS_CONFIG nStereoBands;
...@@ -65,38 +64,14 @@ typedef struct { ...@@ -65,38 +64,14 @@ typedef struct {
/* Function / Class Declarations *********************************************/ /* Function / Class Declarations *********************************************/
typedef struct T_PS_QMF_DATA
{
FIXP_QMF *rQmfData[PSENC_QMF_BUFFER_LENGTH];
FIXP_QMF *iQmfData[PSENC_QMF_BUFFER_LENGTH];
INT nCols;
INT nRows;
INT bufferReadOffset;
INT bufferReadOffsetHybrid;
INT bufferWriteOffset;
INT bufferLength;
} PS_QMF_DATA, *HANDLE_PS_QMF_DATA;
typedef struct T_PS_CHANNEL_DATA {
HANDLE_PS_QMF_DATA hPsQmfData;
int psQmfScale;
HANDLE_PS_HYBRID_DATA hHybData;
HANDLE_PS_HYBRID hHybAna;
INT psChannelDelay; /* delay in samples */
} PS_CHANNEL_DATA, *HANDLE_PS_CHANNEL_DATA;
typedef struct T_PARAMETRIC_STEREO { typedef struct T_PARAMETRIC_STEREO {
HANDLE_PS_HYBRID_CONFIG hHybridConfig;
HANDLE_PS_CHANNEL_DATA hPsChannelData[MAX_PS_CHANNELS];
HANDLE_PS_ENCODE hPsEncode; HANDLE_PS_ENCODE hPsEncode;
HANDLE_PS_OUT hPsOut[2]; PS_OUT psOut[2];
FIXP_QMF *qmfDelayReal[QMF_MAX_TIME_SLOTS>>1]; FIXP_DBL __staticHybridData[HYBRID_READ_OFFSET][MAX_PS_CHANNELS][2][MAX_HYBRID_BANDS];
FIXP_QMF *qmfDelayImag[QMF_MAX_TIME_SLOTS>>1]; FIXP_DBL *pHybridData[HYBRID_READ_OFFSET+HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2];
FIXP_QMF *qmfDelayRealRef;
FIXP_QMF *qmfDelayImagRef; FIXP_QMF qmfDelayLines[2][QMF_MAX_TIME_SLOTS>>1][QMF_CHANNELS];
int qmfDelayScale; int qmfDelayScale;
INT psDelay; INT psDelay;
...@@ -108,12 +83,15 @@ typedef struct T_PARAMETRIC_STEREO { ...@@ -108,12 +83,15 @@ typedef struct T_PARAMETRIC_STEREO {
INT noQmfSlots; INT noQmfSlots;
INT noQmfBands; INT noQmfBands;
} PARAMETRIC_STEREO; FIXP_DBL __staticHybAnaStatesLF[MAX_PS_CHANNELS][2*HYBRID_FILTER_LENGTH*HYBRID_MAX_QMF_BANDS];
FIXP_DBL __staticHybAnaStatesHF[MAX_PS_CHANNELS][2*HYBRID_FILTER_DELAY*(QMF_CHANNELS-HYBRID_MAX_QMF_BANDS)];
FDK_ANA_HYB_FILTER fdkHybAnaFilter[MAX_PS_CHANNELS];
FDK_SYN_HYB_FILTER fdkHybSynFilter;
} PARAMETRIC_STEREO;
typedef struct T_PSENC_CONFIG { typedef struct T_PSENC_CONFIG {
INT frameSize; INT frameSize;
INT qmfFilterMode; INT qmfFilterMode;
INT sbrPsDelay; INT sbrPsDelay;
...@@ -126,35 +104,105 @@ typedef struct T_PSENC_CONFIG { ...@@ -126,35 +104,105 @@ typedef struct T_PSENC_CONFIG {
typedef struct T_PARAMETRIC_STEREO *HANDLE_PARAMETRIC_STEREO; typedef struct T_PARAMETRIC_STEREO *HANDLE_PARAMETRIC_STEREO;
HANDLE_ERROR_INFO /**
PSEnc_Create(HANDLE_PARAMETRIC_STEREO *phParametricStereo); * \brief Create a parametric stereo encoder instance.
*
* \param phParametricStereo A pointer to a parametric stereo handle to be allocated. Initialized on return.
*
* \return
* - PSENC_OK, on succes.
* - PSENC_INVALID_HANDLE, PSENC_MEMORY_ERROR, on failure.
*/
FDK_PSENC_ERROR PSEnc_Create(
HANDLE_PARAMETRIC_STEREO *phParametricStereo
);
HANDLE_ERROR_INFO /**
PSEnc_Init(HANDLE_PARAMETRIC_STEREO hParametricStereo, * \brief Initialize a parametric stereo encoder instance.
HANDLE_PSENC_CONFIG hPsEncConfig, *
* \param hParametricStereo Meta Data handle.
* \param hPsEncConfig Filled parametric stereo configuration structure.
* \param noQmfSlots Number of slots within one audio frame.
* \param noQmfBands Number of QMF bands.
* \param dynamic_RAM Pointer to preallocated workbuffer.
*
* \return
* - PSENC_OK, on succes.
* - PSENC_INVALID_HANDLE, PSENC_INIT_ERROR, on failure.
*/
FDK_PSENC_ERROR PSEnc_Init(
HANDLE_PARAMETRIC_STEREO hParametricStereo,
const HANDLE_PSENC_CONFIG hPsEncConfig,
INT noQmfSlots, INT noQmfSlots,
INT noQmfBands INT noQmfBands
,UCHAR *dynamic_RAM ,UCHAR *dynamic_RAM
); );
HANDLE_ERROR_INFO
UpdatePSQmfData_second(HANDLE_PARAMETRIC_STEREO hParametricStereo);
HANDLE_ERROR_INFO /**
PSEnc_Destroy(HANDLE_PARAMETRIC_STEREO *hParametricStereo); * \brief Destroy parametric stereo encoder instance.
*
* Deallocate instance and free whole memory.
*
* \param phParametricStereo Pointer to the parametric stereo handle to be deallocated.
*
* \return
* - PSENC_OK, on succes.
* - PSENC_INVALID_HANDLE, on failure.
*/
FDK_PSENC_ERROR PSEnc_Destroy(
HANDLE_PARAMETRIC_STEREO *phParametricStereo
);
HANDLE_ERROR_INFO /**
FDKsbrEnc_PSEnc_ParametricStereoProcessing(HANDLE_PARAMETRIC_STEREO hParametricStereo, * \brief Apply parametric stereo processing.
FIXP_QMF **RESTRICT qmfRealData, *
FIXP_QMF **RESTRICT qmfImagData, * \param hParametricStereo Meta Data handle.
INT qmfOffset, * \param samples Pointer to 2 channel audio input signal.
* \param timeInStride, Stride factor of input buffer.
* \param hQmfAnalysis, Pointer to QMF analysis filterbanks.
* \param downmixedRealQmfData Pointer to real QMF buffer to be written to.
* \param downmixedImagQmfData Pointer to imag QMF buffer to be written to.
* \param downsampledOutSignal Pointer to buffer where to write downmixed timesignal.
* \param sbrSynthQmf Pointer to QMF synthesis filterbank.
* \param qmfScale Return scaling factor of the qmf data.
* \param sendHeader Signal whether to write header data.
*
* \return
* - PSENC_OK, on succes.
* - PSENC_INVALID_HANDLE, PSENC_ENCODE_ERROR, on failure.
*/
FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing(
HANDLE_PARAMETRIC_STEREO hParametricStereo,
INT_PCM *samples[2],
UINT timeInStride,
QMF_FILTER_BANK **hQmfAnalysis,
FIXP_QMF **RESTRICT downmixedRealQmfData,
FIXP_QMF **RESTRICT downmixedImagQmfData,
INT_PCM *downsampledOutSignal, INT_PCM *downsampledOutSignal,
HANDLE_QMF_FILTER_BANK sbrSynthQmf, HANDLE_QMF_FILTER_BANK sbrSynthQmf,
SCHAR *qmfScale, SCHAR *qmfScale,
const int sendHeader); const int sendHeader
);
INT
FDKsbrEnc_PSEnc_WritePSData(HANDLE_PARAMETRIC_STEREO hParametricStereo, HANDLE_FDK_BITSTREAM hBitstream); /**
* \brief Write parametric stereo bitstream.
*
* Write ps_data() element to bitstream and return number of written bits.
* Returns number of written bits only, if hBitstream == NULL.
*
* \param hParametricStereo Meta Data handle.
* \param hBitstream Bitstream buffer handle.
*
* \return
* - number of written bits.
*/
INT FDKsbrEnc_PSEnc_WritePSData(
HANDLE_PARAMETRIC_STEREO hParametricStereo,
HANDLE_FDK_BITSTREAM hBitstream
);
#endif /* __INCLUDED_PS_MAIN_H */ #endif /* __INCLUDED_PS_MAIN_H */
This diff is collapsed.
/***************************** MPEG Audio Encoder ***************************
(C) Copyright Fraunhofer IIS (2004-2005)
All Rights Reserved
Please be advised that this software and/or program delivery is
Confidential Information of Fraunhofer and subject to and covered by the
Fraunhofer IIS Software Evaluation Agreement
between Google Inc. and Fraunhofer
effective and in full force since March 1, 2012.
You may use this software and/or program only under the terms and
conditions described in the above mentioned Fraunhofer IIS Software
Evaluation Agreement. Any other and/or further use requires a separate agreement.
$Id$
Initial author: M. Neuendorf, M. Multrus
contents/description: hypbrid filter bank (prototypes)
This software and/or program is protected by copyright law and international
treaties. Any reproduction or distribution of this software and/or program,
or any portion of it, may result in severe civil and criminal penalties, and
will be prosecuted to the maximum extent possible under law.
******************************************************************************/
#ifndef __hybrid_h
#define __hybrid_h
/* Includes ******************************************************************/
#include "sbr_def.h"
#include "ps_const.h"
#include "qmf.h"
/* Data Types ****************************************************************/
typedef enum {
HYBRID_2_REAL = 2,
HYBRID_4_CPLX = 4,
HYBRID_6_CPLX = 6,
HYBRID_8_CPLX = 8,
HYBRID_12_CPLX = 12
} HYBRID_RES;
#define MAX_HYBRID_RES (HYBRID_12_CPLX)
/* Defines *******************************************************************/
#define MAX_QMF_BANDS_IN_HYBRID (5)
#define MAX_IID_GROUPS (50) /* NO_IID_GROUPS_HI_RES */
#define HYBRID_FILTER_LENGTH ( 13 )
#define HYBRID_FRAMESIZE ( QMF_MAX_TIME_SLOTS )
#define HYBRID_WRITEOFFSET ( 10 )
#define HYBRID_NUM_BANDS ( 10 )
#define NO_QMF_BANDS_HYBRID_10 ( 3 )
#define NO_QMF_BANDS_HYBRID_20 ( 3 )
#define HYBRID_MAX_QMF_BANDS ( NO_QMF_BANDS_HYBRID_20 )
#define QMF_BUFFER_MOVE ( HYBRID_FILTER_LENGTH - 1 )
/* Data Types ****************************************************************/
typedef struct PS_HYBRID_CONFIG_tag {
PS_BANDS mode;
UINT noQmfBandsInHybrid;
INT aHybridResolution[MAX_QMF_BANDS_IN_HYBRID]; /* valid entries from 0 to noQmfBandsInHybrid */
} PS_HYBRID_CONFIG, *HANDLE_PS_HYBRID_CONFIG;
typedef struct PS_HYBRID_tag
{
PS_BANDS mode;
INT nQmfBands;
INT frameSizeInit;
INT frameSize;
INT pResolution[HYBRID_MAX_QMF_BANDS];
INT qmfBufferMove;
INT hybridFilterDelay;
FIXP_DBL *fft;
FIXP_QMF *pWorkReal; /**< Working arrays for Qmf samples. */
FIXP_QMF *pWorkImag;
FIXP_QMF mQmfBufferReal[HYBRID_MAX_QMF_BANDS][QMF_BUFFER_MOVE]; /**< Stores old Qmf samples. */
FIXP_QMF mQmfBufferImag[HYBRID_MAX_QMF_BANDS][QMF_BUFFER_MOVE];
FIXP_QMF *mTempReal[HYBRID_FRAMESIZE]; /**< Temporary matrices for filter bank output. */
FIXP_QMF *mTempImag[HYBRID_FRAMESIZE];
} PS_HYBRID;
typedef struct PS_HYBRID_DATA_tag {
INT frameSize;
INT nHybridBands;
INT nHybridQmfBands;
INT nHybridResolution [HYBRID_MAX_QMF_BANDS];
FIXP_QMF* rHybData [(HYBRID_FRAMESIZE + HYBRID_WRITEOFFSET)];
FIXP_QMF* iHybData [(HYBRID_FRAMESIZE + HYBRID_WRITEOFFSET)];
SCHAR sf_fixpHybrid;
INT hybDataReadOffset;
INT hybDataWriteOffset;
} PS_HYBRID_DATA;
typedef struct PS_HYBRID_DATA_tag *HANDLE_PS_HYBRID_DATA;
typedef struct PS_HYBRID_tag *HANDLE_PS_HYBRID;
/* Function Declarations *********************************************/
/*****************************************************************************/
/* **** FILTERBANK CONFIG **** */
HANDLE_ERROR_INFO FDKsbrEnc_CreateHybridConfig(HANDLE_PS_HYBRID_CONFIG *phHybConfig,
PS_BANDS mode);
/*****************************************************************************/
/* **** FILTERBANK DATA **** */
HANDLE_ERROR_INFO FDKsbrEnc_CreateHybridData(HANDLE_PS_HYBRID_DATA *phHybData,
INT ch);
HANDLE_ERROR_INFO FDKsbrEnc_InitHybridData(HANDLE_PS_HYBRID_DATA hHybData,
HANDLE_PS_HYBRID_CONFIG hHybConfig,
INT frameSize);
HANDLE_ERROR_INFO FDKsbrEnc_DestroyHybridData(HANDLE_PS_HYBRID_DATA* phHybData);
inline INT FDKsbrEnc_GetHybridFrameSize(HANDLE_PS_HYBRID_DATA h) {
return h->frameSize;
}
inline INT FDKsbrEnc_GetNumberHybridBands(HANDLE_PS_HYBRID_DATA h) {
return h->nHybridBands;
}
inline INT FDKsbrEnc_GetNumberHybridQmfBands(HANDLE_PS_HYBRID_DATA h) {
return h->nHybridQmfBands;
}
INT FDKsbrEnc_GetHybridResolution(HANDLE_PS_HYBRID_DATA h, INT qmfBand);
/*****************************************************************************/
/* **** FILTERBANK **** */
HANDLE_ERROR_INFO
FDKsbrEnc_CreateHybridFilterBank ( HANDLE_PS_HYBRID *phHybrid,
INT ch );
HANDLE_ERROR_INFO
FDKsbrEnc_InitHybridFilterBank ( HANDLE_PS_HYBRID hHybrid,
HANDLE_PS_HYBRID_CONFIG hHybConfig,
INT frameSize );
HANDLE_ERROR_INFO
FDKsbrEnc_DeleteHybridFilterBank ( HANDLE_PS_HYBRID* phHybrid );
HANDLE_ERROR_INFO
HybridAnalysis ( HANDLE_PS_HYBRID hHybrid,
FIXP_QMF *const * const mQmfReal,
FIXP_QMF *const * const mQmfImag,
SCHAR sf_fixpQmf,
FIXP_QMF **mHybridReal,
FIXP_QMF **mHybridImag,
SCHAR *sf_fixpHybrid);
INT
FDKsbrEnc_GetHybridFilterDelay(HANDLE_PS_HYBRID hHybrid);
#endif /*__hybrid_h*/
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
*******************************************************************************/ *******************************************************************************/
/*! /*!
\file \file
\brief Main SBR structs definitions $Revision: 36847 $ \brief Main SBR structs definitions $Revision: 37142 $
*/ */
#ifndef __SBR_H #ifndef __SBR_H
...@@ -92,7 +92,6 @@ struct SBR_ENCODER ...@@ -92,7 +92,6 @@ struct SBR_ENCODER
UCHAR* dynamicRam; UCHAR* dynamicRam;
UCHAR* pSBRdynamic_RAM; UCHAR* pSBRdynamic_RAM;
HANDLE_PSENC_CONFIG hPsEncConfig;
HANDLE_PARAMETRIC_STEREO hParametricStereo; HANDLE_PARAMETRIC_STEREO hParametricStereo;
QMF_FILTER_BANK qmfSynthesisPS; QMF_FILTER_BANK qmfSynthesisPS;
......
This diff is collapsed.
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/*! /*!
\file \file
\brief Memory layout \brief Memory layout
$Revision: 36847 $ $Revision: 37142 $
This module declares all static and dynamic memory spaces This module declares all static and dynamic memory spaces
*/ */
...@@ -114,39 +114,10 @@ C_ALLOC_MEM2 (Ram_Sbr_guideVectorOrig, FIXP_DBL, (MAX_NO_OF_ESTIMATES*MAX_FREQ_C ...@@ -114,39 +114,10 @@ C_ALLOC_MEM2 (Ram_Sbr_guideVectorOrig, FIXP_DBL, (MAX_NO_OF_ESTIMATES*MAX_FREQ_C
*/ */
C_AALLOC_MEM_L(Ram_PsQmfStatesSynthesis, FIXP_DBL, QMF_FILTER_LENGTH/2, SECT_DATA_L1) C_AALLOC_MEM_L(Ram_PsQmfStatesSynthesis, FIXP_DBL, QMF_FILTER_LENGTH/2, SECT_DATA_L1)
C_ALLOC_MEM (Ram_PsEnvRBuffer, FIXP_DBL, QMF_MAX_TIME_SLOTS*QMF_CHANNELS/2)
C_ALLOC_MEM (Ram_PsEnvIBuffer, FIXP_DBL, QMF_MAX_TIME_SLOTS*QMF_CHANNELS/2)
C_ALLOC_MEM2 (Ram_PsChData, PS_CHANNEL_DATA, 1, MAX_PS_CHANNELS)
C_ALLOC_MEM (Ram_PsEncConf, PSENC_CONFIG, 1)
C_ALLOC_MEM_L (Ram_PsEncode, PS_ENCODE, 1, SECT_DATA_L1) C_ALLOC_MEM_L (Ram_PsEncode, PS_ENCODE, 1, SECT_DATA_L1)
C_ALLOC_MEM (Ram_PsData, PS_DATA, 1)
C_ALLOC_MEM (Ram_ParamStereo, PARAMETRIC_STEREO, 1) C_ALLOC_MEM (Ram_ParamStereo, PARAMETRIC_STEREO, 1)
C_ALLOC_MEM2 (Ram_PsOut, PS_OUT, 1, 2)
/* QMF data
*/
C_ALLOC_MEM (Ram_PsQmfNewSamples, FIXP_DBL, QMF_CHANNELS)
C_ALLOC_MEM2 (Ram_PsQmfData, PS_QMF_DATA, 1, MAX_PS_CHANNELS)
/* HYBRID data
*/
C_AALLOC_MEM (Ram_PsHybFFT, FIXP_DBL, 16)
C_ALLOC_MEM2(Ram_HybData, PS_HYBRID_DATA, 1, MAX_PS_CHANNELS)
C_ALLOC_MEM2(Ram_PsHybrid, PS_HYBRID, 1, MAX_PS_CHANNELS)
C_ALLOC_MEM (Ram_PsHybConfig, PS_HYBRID_CONFIG, 1)
C_ALLOC_MEM2(Ram_PsRhyb, FIXP_QMF, ((HYBRID_FRAMESIZE+HYBRID_WRITEOFFSET)*HYBRID_NUM_BANDS), MAX_PS_CHANNELS)
C_ALLOC_MEM2(Ram_PsIhyb, FIXP_QMF, ((HYBRID_FRAMESIZE+HYBRID_WRITEOFFSET)*HYBRID_NUM_BANDS), MAX_PS_CHANNELS)
C_ALLOC_MEM (Ram_PsHybWkReal, FIXP_QMF, (HYBRID_FRAMESIZE + QMF_BUFFER_MOVE))
C_ALLOC_MEM (Ram_PsHybWkImag, FIXP_QMF, (HYBRID_FRAMESIZE + QMF_BUFFER_MOVE))
C_ALLOC_MEM2(Ram_PsMtmpReal, FIXP_QMF, (MAX_HYBRID_RES), HYBRID_FRAMESIZE)
C_ALLOC_MEM2(Ram_PsMtmpImag, FIXP_QMF, (MAX_HYBRID_RES), HYBRID_FRAMESIZE)
/* @} */ /* @} */
...@@ -175,38 +146,11 @@ C_ALLOC_MEM2(Ram_PsMtmpImag, FIXP_QMF, (MAX_HYBRID_RES), HYBRID_FRAMESIZE) ...@@ -175,38 +146,11 @@ C_ALLOC_MEM2(Ram_PsMtmpImag, FIXP_QMF, (MAX_HYBRID_RES), HYBRID_FRAMESIZE)
/* The SBR encoder uses a single channel overlapping buffer set (always n=0), but PS does not. */ /* The SBR encoder uses a single channel overlapping buffer set (always n=0), but PS does not. */
FIXP_DBL* GetRam_Sbr_envRBuffer (int n, UCHAR* dynamic_RAM) { FIXP_DBL* GetRam_Sbr_envRBuffer (int n, UCHAR* dynamic_RAM) {
FDK_ASSERT(dynamic_RAM!=0); FDK_ASSERT(dynamic_RAM!=0);
return ((FIXP_DBL*) (dynamic_RAM + OFFSET_QMF + (n*ENV_R_BUFF_BYTE*2) )); return ((FIXP_DBL*) (dynamic_RAM + OFFSET_QMF + (n*(ENV_R_BUFF_BYTE+ENV_I_BUFF_BYTE)) ));
} }
FIXP_DBL* GetRam_Sbr_envIBuffer (int n, UCHAR* dynamic_RAM) { FIXP_DBL* GetRam_Sbr_envIBuffer (int n, UCHAR* dynamic_RAM) {
FDK_ASSERT(dynamic_RAM!=0); FDK_ASSERT(dynamic_RAM!=0);
//return ((FIXP_DBL*) (dynamic_RAM + OFFSET_QMF + (MAX_NUM_CHANNELS*ENV_R_BUFF_BYTE) + n*ENV_I_BUFF_BYTE)); return ((FIXP_DBL*) (dynamic_RAM + OFFSET_QMF + (ENV_R_BUFF_BYTE) + (n*(ENV_R_BUFF_BYTE+ENV_I_BUFF_BYTE))));
return ((FIXP_DBL*) (dynamic_RAM + OFFSET_QMF + (ENV_R_BUFF_BYTE) + (n*ENV_I_BUFF_BYTE*2)));
}
/* reuse QMF buffer in PS module. We Require space to hold 2 channels. */
C_ALLOC_MEM2(Ram_PsRqmf, FIXP_QMF, ((PSENC_QMF_BUFFER_LENGTH-QMF_MAX_TIME_SLOTS)*(QMF_CHANNELS)), MAX_PS_CHANNELS)
C_ALLOC_MEM2(Ram_PsIqmf, FIXP_QMF, ((PSENC_QMF_BUFFER_LENGTH-QMF_MAX_TIME_SLOTS)*(QMF_CHANNELS)), MAX_PS_CHANNELS)
FIXP_QMF* FDKsbrEnc_SliceRam_PsRqmf(FIXP_DBL* rQmfData, UCHAR* dynamic_RAM, int ch, int i, int qmfSlots)
{
FDK_ASSERT(dynamic_RAM!=0);
if (i<HYBRID_READ_OFFSET)
return rQmfData + (i*(QMF_CHANNELS));
else if ((i<(HYBRID_READ_OFFSET+qmfSlots)))
return GetRam_Sbr_envRBuffer(ch, dynamic_RAM) + ( (i-(HYBRID_READ_OFFSET))*(QMF_CHANNELS) );
else
return rQmfData + ((i-qmfSlots)*(QMF_CHANNELS));
}
FIXP_QMF* FDKsbrEnc_SliceRam_PsIqmf(FIXP_DBL* iQmfData, UCHAR* dynamic_RAM, int ch, int i, int qmfSlots)
{
FDK_ASSERT(dynamic_RAM!=0);
if (i<HYBRID_READ_OFFSET)
return iQmfData + (i*(QMF_CHANNELS));
else if ((i<(HYBRID_READ_OFFSET+qmfSlots)))
return GetRam_Sbr_envIBuffer(ch, dynamic_RAM) + ( (i-(HYBRID_READ_OFFSET))*(QMF_CHANNELS) );
else
return iQmfData + ((i-qmfSlots)*(QMF_CHANNELS));
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/*! /*!
\file \file
\brief Declaration of constant tables \brief Declaration of constant tables
$Revision: 36847 $ $Revision: 37577 $
*/ */
#ifndef __SBR_ROM_H #ifndef __SBR_ROM_H
#define __SBR_ROM_H #define __SBR_ROM_H
...@@ -60,7 +60,11 @@ extern const UCHAR v_Huff_NoiseLevelL11T[63]; ...@@ -60,7 +60,11 @@ extern const UCHAR v_Huff_NoiseLevelL11T[63];
extern const INT bookSbrNoiseBalanceC11T[25]; extern const INT bookSbrNoiseBalanceC11T[25];
extern const UCHAR bookSbrNoiseBalanceL11T[25]; extern const UCHAR bookSbrNoiseBalanceL11T[25];
#define SBRENC_TUNING_SIZE (126 + 37) #define SBRENC_AACLC_TUNING_SIZE 124
#define SBRENC_AACELD_TUNING_SIZE 35
#define SBRENC_AACELD2_TUNING_SIZE 31
#define SBRENC_TUNING_SIZE (SBRENC_AACLC_TUNING_SIZE + SBRENC_AACELD_TUNING_SIZE)
extern const sbrTuningTable_t sbrTuningTable[SBRENC_TUNING_SIZE]; extern const sbrTuningTable_t sbrTuningTable[SBRENC_TUNING_SIZE];
......
...@@ -236,6 +236,7 @@ typedef enum { ...@@ -236,6 +236,7 @@ typedef enum {
#define CC_IS_BASELAYER 0x00200000 #define CC_IS_BASELAYER 0x00200000
#define CC_PROTECTION 0x00400000 #define CC_PROTECTION 0x00400000
#define CC_SBR 0x00800000 #define CC_SBR 0x00800000
#define CC_SBRCRC 0x00010000
#define CC_RVLC 0x01000000 #define CC_RVLC 0x01000000
#define CC_VCB11 0x02000000 #define CC_VCB11 0x02000000
#define CC_HCR 0x04000000 #define CC_HCR 0x04000000
...@@ -284,6 +285,11 @@ typedef enum ...@@ -284,6 +285,11 @@ typedef enum
ID_LAST ID_LAST
} MP4_ELEMENT_ID; } MP4_ELEMENT_ID;
#define IS_CHANNEL_ELEMENT(elementId) \
((elementId) == ID_SCE \
|| (elementId) == ID_CPE \
|| (elementId) == ID_LFE)
#define EXT_ID_BITS 4 /**< Size in bits of extension payload type tags. */ #define EXT_ID_BITS 4 /**< Size in bits of extension payload type tags. */
/** Extension payload types. */ /** Extension payload types. */
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment