diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2013-08-27 16:28:09 -0700 |
---|---|---|
committer | Jean-Michel Trivi <jmtrivi@google.com> | 2013-08-27 16:28:09 -0700 |
commit | 5016eb7f6582fbb2d72d79be782325a12df08864 (patch) | |
tree | bc2325ebc6840a20d25f35a0c5a6a13454d2e402 /libMpegTPDec/src/tpdec_asc.cpp | |
parent | b9774f90651be61065ae40171fc321f6ced60e49 (diff) | |
download | ODR-AudioEnc-5016eb7f6582fbb2d72d79be782325a12df08864.tar.gz ODR-AudioEnc-5016eb7f6582fbb2d72d79be782325a12df08864.tar.bz2 ODR-AudioEnc-5016eb7f6582fbb2d72d79be782325a12df08864.zip |
Decoder stability, sanity checks improvements
* AAC-Decoder
- Improved PCE handling for saver (re-)configuration and metadata processing.
Modified file(s):
libAACdec/src/aacdecoder.cpp
libAACdec/src/aacdecoder_lib.cpp
- Transport layer changes (config found) -> to be evaluated.
Modified file(s):
libMpegTPDec/include/tpdec_lib.h
libMpegTPDec/src/tpdec_latm.h
libMpegTPDec/src/version
libMpegTPDec/src/tpdec_asc.cpp
libMpegTPDec/src/tpdec_lib.cpp
libMpegTPDec/src/tpdec_adts.cpp
libMpegTPDec/src/tpdec_latm.cpp
libSYS/include/FDK_audio.h
libSYS/src/genericStds.cpp
- Enable concealment state machine to skip states if the corresponding
parameter is set to zero.
Modified file(s):
libAACdec/src/conceal.cpp
- Add some more sanity checks to avoid segmentation faults especially when
setting dynamic API params.
Modified file(s):
libAACdec/src/aacdecoder_lib.cpp
- Fix to do a fail-safe initialization of IMDCT for all channels even with
corrupt streams.
Modified file(s):
libAACdec/src/aacdecoder.cpp
- HCR decoder fix (remove warnings).
Modified file(s):
libAACdec/src/block.cpp
- Fix border calculation in SBR decoder's LPP transposer patch determination.
Modified file(s):
libSBRdec/src/env_dec.cpp
libSBRdec/src/sbrdecoder.cpp
libSBRdec/src/lpp_tran.cpp
Bug 9428126
Change-Id: Ib415b702b88a7ec8e9a55789d79cafb39296d26b
Diffstat (limited to 'libMpegTPDec/src/tpdec_asc.cpp')
-rw-r--r-- | libMpegTPDec/src/tpdec_asc.cpp | 147 |
1 files changed, 143 insertions, 4 deletions
diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index e6278d6..59ad58b 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -205,6 +205,145 @@ void CProgramConfig_Read( pPce->isValid = 1; } + +/* + * Compare two program configurations. + * Returns the result of the comparison: + * -1 - completely different + * 0 - completely equal + * 1 - different but same channel configuration + * 2 - different channel configuration but same number of channels + */ +int CProgramConfig_Compare ( const CProgramConfig * const pPce1, + const CProgramConfig * const pPce2 ) +{ + int result = 0; /* Innocent until proven false. */ + + if (FDKmemcmp(pPce1, pPce2, sizeof(CProgramConfig)) != 0) + { /* Configurations are not completely different. + So look into details and analyse the channel configurations: */ + result = -1; + + if (pPce1->NumChannels == pPce2->NumChannels) + { /* Now the logic changes. We first assume to have the same channel configuration + and then prove if this assumption is true. */ + result = 1; + + /* Front channels */ + if (pPce1->NumFrontChannelElements != pPce2->NumFrontChannelElements) { + result = 2; /* different number of front channel elements */ + } else { + int el, numCh1 = 0, numCh2 = 0; + for (el = 0; el < pPce1->NumFrontChannelElements; el += 1) { + numCh1 += pPce1->FrontElementIsCpe[el] ? 2 : 1; + numCh2 += pPce2->FrontElementIsCpe[el] ? 2 : 1; + } + if (numCh1 != numCh2) { + result = 2; /* different number of front channels */ + } + } + /* Side channels */ + if (pPce1->NumSideChannelElements != pPce2->NumSideChannelElements) { + result = 2; /* different number of side channel elements */ + } else { + int el, numCh1 = 0, numCh2 = 0; + for (el = 0; el < pPce1->NumSideChannelElements; el += 1) { + numCh1 += pPce1->SideElementIsCpe[el] ? 2 : 1; + numCh2 += pPce2->SideElementIsCpe[el] ? 2 : 1; + } + if (numCh1 != numCh2) { + result = 2; /* different number of side channels */ + } + } + /* Back channels */ + if (pPce1->NumBackChannelElements != pPce2->NumBackChannelElements) { + result = 2; /* different number of back channel elements */ + } else { + int el, numCh1 = 0, numCh2 = 0; + for (el = 0; el < pPce1->NumBackChannelElements; el += 1) { + numCh1 += pPce1->BackElementIsCpe[el] ? 2 : 1; + numCh2 += pPce2->BackElementIsCpe[el] ? 2 : 1; + } + if (numCh1 != numCh2) { + result = 2; /* different number of back channels */ + } + } + /* LFE channels */ + if (pPce1->NumLfeChannelElements != pPce2->NumLfeChannelElements) { + result = 2; /* different number of lfe channels */ + } + /* LFEs are always SCEs so we don't need to count the channels. */ + } + } + + return result; +} + +void CProgramConfig_GetDefault( CProgramConfig *pPce, + const UINT channelConfig ) +{ + FDK_ASSERT(pPce != NULL); + + /* Init PCE */ + CProgramConfig_Init(pPce); + pPce->Profile = 1; /* Set AAC LC because it is the only supported object type. */ + + switch (channelConfig) { + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case 6: /* 3/0/2.1ch */ + pPce->NumLfeChannelElements += 1; + pPce->NumChannels += 1; + case 5: /* 3/0/2.0ch */ + case 4: /* 3/0/1.0ch */ + pPce->NumBackChannelElements += 1; + pPce->BackElementIsCpe[0] = (channelConfig>4) ? 1 : 0; + pPce->NumChannels += (channelConfig>4) ? 2 : 1; + pPce->NumEffectiveChannels += (channelConfig>4) ? 2 : 1; + case 3: /* 3/0/0.0ch */ + pPce->NumFrontChannelElements += 1; + pPce->FrontElementIsCpe[1] = 1; + pPce->NumChannels += 2; + pPce->NumEffectiveChannels += 2; + case 1: /* 1/0/0.0ch */ + pPce->NumFrontChannelElements += 1; + pPce->FrontElementIsCpe[0] = 0; + pPce->NumChannels += 1; + pPce->NumEffectiveChannels += 1; + pPce->isValid = 1; + break; + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case 2: /* 2/0/0.ch */ + pPce->NumFrontChannelElements = 1; + pPce->FrontElementIsCpe[0] = 1; + pPce->NumChannels += 2; + pPce->NumEffectiveChannels += 2; + pPce->isValid = 1; + break; + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + default: + pPce->isValid = 0; /* To be explicit! */ + break; + } + + if (pPce->isValid) { + /* Create valid element instance tags */ + int el, elTagSce = 0, elTagCpe = 0; + + for (el = 0; el < pPce->NumFrontChannelElements; el += 1) { + pPce->FrontElementTagSelect[el] = (pPce->FrontElementIsCpe) ? elTagCpe++ : elTagSce++; + } + for (el = 0; el < pPce->NumSideChannelElements; el += 1) { + pPce->SideElementTagSelect[el] = (pPce->SideElementIsCpe) ? elTagCpe++ : elTagSce++; + } + for (el = 0; el < pPce->NumBackChannelElements; el += 1) { + pPce->BackElementTagSelect[el] = (pPce->BackElementIsCpe) ? elTagCpe++ : elTagSce++; + } + elTagSce = 0; + for (el = 0; el < pPce->NumLfeChannelElements; el += 1) { + pPce->LfeElementTagSelect[el] = elTagSce++; + } + } +} #endif /* TP_PCE_ENABLE */ /** @@ -589,18 +728,18 @@ static INT ld_sbr_header( const CSAudioSpecificConfig *asc, } switch ( channelConfiguration ) { + case 7: + error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++); + case 6: case 5: error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++); case 3: error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++); break; - case 7: - error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_SCE, i++); - case 6: - error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++); case 4: error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++); + error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_SCE, i++); break; } |