summaryrefslogtreecommitdiffstats
path: root/libAACdec/src/aacdecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libAACdec/src/aacdecoder.cpp')
-rw-r--r--libAACdec/src/aacdecoder.cpp188
1 files changed, 120 insertions, 68 deletions
diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp
index 3a2a561..e19c501 100644
--- a/libAACdec/src/aacdecoder.cpp
+++ b/libAACdec/src/aacdecoder.cpp
@@ -338,17 +338,22 @@ AAC_DECODER_ERROR CAacDecoder_AncDataParse (
\return Error code
*/
static AAC_DECODER_ERROR CDataStreamElement_Read (
+ HANDLE_AACDECODER self,
HANDLE_FDK_BITSTREAM bs,
- CAncData *ancData,
- HANDLE_AAC_DRC hDrcInfo,
- HANDLE_TRANSPORTDEC pTp,
UCHAR *elementInstanceTag,
UINT alignmentAnchor )
{
+ HANDLE_TRANSPORTDEC pTp;
+ CAncData *ancData;
AAC_DECODER_ERROR error = AAC_DEC_OK;
- UINT dataStart;
+ UINT dataStart, dseBits;
int dataByteAlignFlag, count;
+ FDK_ASSERT(self != NULL);
+
+ ancData = &self->ancData;
+ pTp = self->hInput;
+
int crcReg = transportDec_CrcStartReg(pTp, 0);
/* Element Instance Tag */
@@ -361,6 +366,7 @@ static AAC_DECODER_ERROR CDataStreamElement_Read (
if (count == 255) {
count += FDKreadBits(bs,8); /* EscCount */
}
+ dseBits = count*8;
if (dataByteAlignFlag) {
FDKbyteAlign(bs, alignmentAnchor);
@@ -372,19 +378,29 @@ static AAC_DECODER_ERROR CDataStreamElement_Read (
transportDec_CrcEndReg(pTp, crcReg);
{
- INT readBits, dataBits = count<<3;
-
/* Move to the beginning of the data junk */
FDKpushBack(bs, dataStart-FDKgetValidBits(bs));
/* Read Anc data if available */
- readBits = aacDecoder_drcMarkPayload( hDrcInfo, bs, DVB_DRC_ANC_DATA );
+ aacDecoder_drcMarkPayload( self->hDrcInfo, bs, DVB_DRC_ANC_DATA );
+ }
+
+ {
+ PCMDMX_ERROR dmxErr = PCMDMX_OK;
+
+ /* Move to the beginning of the data junk */
+ FDKpushBack(bs, dataStart-FDKgetValidBits(bs));
- if (readBits != dataBits) {
- /* Move to the end again. */
- FDKpushBiDirectional(bs, FDKgetValidBits(bs)-dataStart+dataBits);
+ /* Read DMX meta-data */
+ dmxErr = pcmDmx_Parse (
+ self->hPcmUtils,
+ bs,
+ dseBits,
+ 0 /* not mpeg2 */ );
}
- }
+
+ /* Move to the very end of the element. */
+ FDKpushBiDirectional(bs, FDKgetValidBits(bs)-dataStart+dseBits);
return error;
}
@@ -701,6 +717,12 @@ void CStreamInfoInit(CStreamInfo *pStreamInfo)
pStreamInfo->numChannels = 0;
pStreamInfo->sampleRate = 0;
pStreamInfo->frameSize = 0;
+
+ pStreamInfo->outputDelay = 0;
+
+ /* DRC */
+ pStreamInfo->drcProgRefLev = -1; /* set program reference level to not indicated */
+ pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */
}
/*!
@@ -774,7 +796,7 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self)
if (self == NULL)
return;
- for (ch=0; ch<(6); ch++) {
+ for (ch=0; ch<(8); ch++) {
if (self->pAacDecoderStaticChannelInfo[ch] != NULL) {
if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer != NULL) {
FreeOverlapBuffer (&self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer);
@@ -851,18 +873,19 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
/* valid number of channels -> copy program config element (PCE) from ASC */
FDKmemcpy(&self->pce, &asc->m_progrConfigElement, sizeof(CProgramConfig));
/* Built element table */
- el = CProgramConfig_GetElementTable(&asc->m_progrConfigElement, self->elements, 7);
- for (; el<7; el++) {
+ el = CProgramConfig_GetElementTable(&asc->m_progrConfigElement, self->elements, (8), &self->chMapIndex);
+ for (; el<(8); el++) {
self->elements[el] = ID_NONE;
}
} else {
return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
}
} else {
+ self->chMapIndex = 0;
if (transportDec_GetFormat(self->hInput) == TT_MP4_ADTS) {
/* set default max_channels for memory allocation because in implicit channel mapping mode
we don't know the actual number of channels until we processed at least one raw_data_block(). */
- ascChannels = (6);
+ ascChannels = (8);
} else {
return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
}
@@ -874,26 +897,34 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
case 1: case 2: case 3: case 4: case 5: case 6:
ascChannels = asc->m_channelConfiguration;
break;
- case 7:
+ case 11:
+ ascChannels = 7;
+ break;
+ case 7: case 12: case 14:
ascChannels = 8;
break;
default:
return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
}
+ if (ascChannels > (8)) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
/* Initialize constant mappings for channel config 1-7 */
if (asc->m_channelConfiguration > 0) {
int el;
- FDKmemcpy(self->elements, elementsTab[asc->m_channelConfiguration-1], sizeof(MP4_ELEMENT_ID)*FDKmin(7,7));
- for (el=7; el<7; el++) {
+ FDKmemcpy(self->elements, elementsTab[asc->m_channelConfiguration-1], sizeof(MP4_ELEMENT_ID)*FDKmin(7,(8)));
+ for (el=7; el<(8); el++) {
self->elements[el] = ID_NONE;
}
for (ch=0; ch<ascChannels; ch++) {
self->chMapping[ch] = ch;
}
- for (; ch<(6); ch++) {
+ for (; ch<(8); ch++) {
self->chMapping[ch] = 255;
}
+ self->chMapIndex = asc->m_channelConfiguration;
}
#ifdef TP_PCE_ENABLE
else {
@@ -909,9 +940,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
self->streamInfo.channelConfig = asc->m_channelConfiguration;
- if (ascChannels > (6)) {
- return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
- }
if (self->streamInfo.aot != asc->m_aot) {
self->streamInfo.aot = asc->m_aot;
ascChanged = 1;
@@ -1096,6 +1124,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
MP4_ELEMENT_ID type = ID_NONE; /* Current element type */
INT aacChannels=0; /* Channel counter for channels found in the bitstream */
+ int chOutMapIdx; /* Output channel mapping index (see comment below) */
INT auStartAnchor = (INT)FDKgetValidBits(bs); /* AU start bit buffer position for AU byte alignment */
@@ -1119,12 +1148,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
if (self->streamInfo.channelConfig == 0) {
/* Init Channel/Element mapping table */
- for (ch=0; ch<(6); ch++) {
+ for (ch=0; ch<(8); ch++) {
self->chMapping[ch] = 255;
}
if (!CProgramConfig_IsValid(pce)) {
int el;
- for (el=0; el<7; el++) {
+ for (el=0; el<(8); el++) {
self->elements[el] = ID_NONE;
}
}
@@ -1161,11 +1190,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
CConcealment_InitChannelData(&self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
&self->concealCommonData,
self->streamInfo.aacSamplesPerFrame );
- /* Clear concealment buffers to get rid of the complete history */
- FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo.spectralCoefficient, 1024 * sizeof(FIXP_CNCL));
- FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo.specScale, 8 * sizeof(SHORT));
/* Clear overlap-add buffers to avoid clicks. */
- FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->IMdct.overlap.freq, OverlapBufferSize*sizeof(FIXP_DBL));
+ FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer, OverlapBufferSize*sizeof(FIXP_DBL));
}
}
@@ -1378,10 +1404,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
{
UCHAR element_instance_tag;
- CDataStreamElement_Read( bs,
- &self->ancData,
- self->hDrcInfo,
- self->hInput,
+ CDataStreamElement_Read( self,
+ bs,
&element_instance_tag,
auStartAnchor );
@@ -1401,29 +1425,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
//self->frameOK = 0;
}
}
-
- {
- UCHAR *pDvbAncData = NULL;
- AAC_DECODER_ERROR ancErr;
- int ancIndex;
- int dvbAncDataSize = 0;
-
- /* Ask how many anc data elements are in buffer */
- ancIndex = self->ancData.nrElements - 1;
- /* Get the last one (if available) */
- ancErr = CAacDecoder_AncDataGet( &self->ancData,
- ancIndex,
- &pDvbAncData,
- &dvbAncDataSize );
-
- if (ancErr == AAC_DEC_OK) {
- pcmDmx_ReadDvbAncData (
- self->hPcmUtils,
- pDvbAncData,
- dvbAncDataSize,
- 0 /* not mpeg2 */ );
- }
- }
break;
#ifdef TP_PCE_ENABLE
@@ -1442,9 +1443,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
}
else if ( result > 1 ) {
/* Built element table */
- int elIdx = CProgramConfig_GetElementTable(pce, self->elements, 7);
+ int elIdx = CProgramConfig_GetElementTable(pce, self->elements, (8), &self->chMapIndex);
/* Reset the remaining tabs */
- for ( ; elIdx<7; elIdx++) {
+ for ( ; elIdx<(8); elIdx++) {
self->elements[elIdx] = ID_NONE;
}
/* Make new number of channel persistant */
@@ -1510,10 +1511,19 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
break;
}
}
- if (err == SBRDEC_OK) {
+ switch (err) {
+ case SBRDEC_PARSE_ERROR:
+ /* Can not go on parsing because we do not
+ know the length of the SBR extension data. */
+ FDKpushFor(bs, bitCnt);
+ bitCnt = 0;
+ break;
+ case SBRDEC_OK:
self->sbrEnabled = 1;
- } else {
+ break;
+ default:
self->frameOK = 0;
+ break;
}
}
@@ -1603,13 +1613,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
self->frameOK=0;
}
- /* store or restore the number of channels */
+ /* store or restore the number of channels and the corresponding info */
if ( self->frameOK && !(flags &(AACDEC_CONCEAL|AACDEC_FLUSH)) ) {
- self->concealChannels = aacChannels; /* store */
+ self->aacChannelsPrev = aacChannels; /* store */
+ FDKmemcpy(self->channelTypePrev, self->channelType, (8)*sizeof(AUDIO_CHANNEL_TYPE)); /* store */
+ FDKmemcpy(self->channelIndicesPrev, self->channelIndices, (8)*sizeof(UCHAR)); /* store */
self->sbrEnabledPrev = self->sbrEnabled;
} else {
if (self->aacChannels > 0) {
- aacChannels = self->concealChannels; /* restore */
+ aacChannels = self->aacChannelsPrev; /* restore */
+ FDKmemcpy(self->channelType, self->channelTypePrev, (8)*sizeof(AUDIO_CHANNEL_TYPE)); /* restore */
+ FDKmemcpy(self->channelIndices, self->channelIndicesPrev, (8)*sizeof(UCHAR)); /* restore */
self->sbrEnabled = self->sbrEnabledPrev;
}
}
@@ -1632,12 +1646,31 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
return ErrorStatus;
}
+ /* Setup the output channel mapping. The table below shows the four possibilities:
+ * # | chCfg | PCE | cChCfg | chOutMapIdx
+ * ---+-------+-----+--------+------------------
+ * 1 | > 0 | no | - | chCfg
+ * 2 | 0 | yes | > 0 | cChCfg
+ * 3 | 0 | yes | 0 | aacChannels || 0
+ * 4 | 0 | no | - | aacChannels || 0
+ * ---+-------+-----+--------+------------------
+ * Where chCfg is the channel configuration index from ASC and cChCfg is a corresponding chCfg
+ * derived from a given PCE. The variable aacChannels represents the number of channel found
+ * during bitstream decoding. Due to the structure of the mapping table it can only be used for
+ * mapping if its value is smaller than 7. Otherwise we use the fallback (0) which is a simple
+ * pass-through. The possibility #4 should appear only with MPEG-2 (ADTS) streams. This is
+ * mode is called "implicit channel mapping".
+ */
+ chOutMapIdx = ((self->chMapIndex==0) && (aacChannels<7)) ? aacChannels : self->chMapIndex;
+
/*
Inverse transform
*/
{
int stride, offset, c;
+ /* Turn on/off DRC modules level normalization in digital domain depending on the limiter status. */
+ aacDecoder_drcSetParam( self->hDrcInfo, APPLY_NORMALIZATION, (self->limiterEnableCurr) ? 0 : 1 );
/* Extract DRC control data and map it to channels (without bitstream delay) */
aacDecoder_drcProlog (
self->hDrcInfo,
@@ -1663,13 +1696,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Setup offset and stride for time buffer traversal. */
if (interleaved) {
stride = aacChannels;
- offset = self->channelOutputMapping[aacChannels-1][c];
+ offset = self->channelOutputMapping[chOutMapIdx][c];
} else {
stride = 1;
- offset = self->channelOutputMapping[aacChannels-1][c] * self->streamInfo.aacSamplesPerFrame;
+ offset = self->channelOutputMapping[chOutMapIdx][c] * self->streamInfo.aacSamplesPerFrame;
}
+ if ( flags&AACDEC_FLUSH ) {
+ /* Clear pAacDecoderChannelInfo->pSpectralCoefficient because with AACDEC_FLUSH set it contains undefined data. */
+ FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, sizeof(FIXP_DBL)*self->streamInfo.aacSamplesPerFrame);
+ }
+
/*
Conceal defective spectral data
*/
@@ -1688,12 +1726,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Reset DRC control data for this channel */
aacDecoder_drcInitChannelData ( &self->pAacDecoderStaticChannelInfo[c]->drcData );
}
+ /* The DRC module demands to be called with the gain field holding the gain scale. */
+ self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING;
/* DRC processing */
aacDecoder_drcApply (
self->hDrcInfo,
self->hSbrDecoder,
pAacDecoderChannelInfo,
&self->pAacDecoderStaticChannelInfo[c]->drcData,
+ self->extGain,
c,
self->streamInfo.aacSamplesPerFrame,
self->sbrEnabled
@@ -1711,6 +1752,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
(self->frameOK && !(flags&AACDEC_CONCEAL)),
self->aacCommonData.workBufferCore1->mdctOutTemp
);
+ self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
break;
case AACDEC_RENDER_ELDFB:
CBlock_FrequencyToTimeLowDelay(
@@ -1720,6 +1762,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
self->streamInfo.aacSamplesPerFrame,
stride
);
+ self->extGainDelay = (self->streamInfo.aacSamplesPerFrame*2 - self->streamInfo.aacSamplesPerFrame/2 - 1)/2;
break;
default:
ErrorStatus = AAC_DEC_UNKNOWN;
@@ -1743,11 +1786,20 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
);
}
+ /* Add additional concealment delay */
+ self->streamInfo.outputDelay += CConcealment_GetDelay(&self->concealCommonData) * self->streamInfo.aacSamplesPerFrame;
+
+ /* Map DRC data to StreamInfo structure */
+ aacDecoder_drcGetInfo (
+ self->hDrcInfo,
+ &self->streamInfo.drcPresMode,
+ &self->streamInfo.drcProgRefLev
+ );
/* Reorder channel type information tables. */
{
- AUDIO_CHANNEL_TYPE types[(6)];
- UCHAR idx[(6)];
+ AUDIO_CHANNEL_TYPE types[(8)];
+ UCHAR idx[(8)];
int c;
FDK_ASSERT(sizeof(self->channelType) == sizeof(types));
@@ -1757,8 +1809,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
FDKmemcpy(idx, self->channelIndices, sizeof(idx));
for (c=0; c<aacChannels; c++) {
- self->channelType[self->channelOutputMapping[aacChannels-1][c]] = types[c];
- self->channelIndices[self->channelOutputMapping[aacChannels-1][c]] = idx[c];
+ self->channelType[self->channelOutputMapping[chOutMapIdx][c]] = types[c];
+ self->channelIndices[self->channelOutputMapping[chOutMapIdx][c]] = idx[c];
}
}