diff options
Diffstat (limited to 'libAACdec/src/aacdecoder.cpp')
-rw-r--r-- | libAACdec/src/aacdecoder.cpp | 188 |
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]; } } |