aboutsummaryrefslogtreecommitdiffstats
path: root/libMpegTPDec/src/tpdec_asc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libMpegTPDec/src/tpdec_asc.cpp')
-rw-r--r--libMpegTPDec/src/tpdec_asc.cpp60
1 files changed, 50 insertions, 10 deletions
diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp
index b0f1c6a..28bc22d 100644
--- a/libMpegTPDec/src/tpdec_asc.cpp
+++ b/libMpegTPDec/src/tpdec_asc.cpp
@@ -139,7 +139,7 @@ static const MP4_ELEMENT_ID channel_configuration_13[] = {
ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_LFE, ID_SCE,
ID_CPE, ID_CPE, ID_SCE, ID_CPE, ID_SCE, ID_SCE, ID_CPE, ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_14[] = {
- ID_SCE, ID_CPE, ID_CPE, ID_LAST, ID_CPE, ID_NONE};
+ ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_CPE, ID_NONE};
static const MP4_ELEMENT_ID *channel_configuration_array[] = {
channel_configuration_0, channel_configuration_1,
@@ -467,6 +467,7 @@ void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig) {
pPce->BackElementIsCpe[1] = 1;
pPce->NumChannels += 1;
pPce->NumEffectiveChannels += 1;
+ FDK_FALLTHROUGH;
case 11: /* 3/0/3.1ch */
pPce->NumFrontChannelElements += 2;
pPce->FrontElementIsCpe[0] = 0;
@@ -482,25 +483,30 @@ void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig) {
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case 14: /* 2/0/0-3/0/2-0.1ch front height */
pPce->FrontElementHeightInfo[2] = 1; /* Top speaker */
- case 7: /* 5/0/2.1ch front */
+ FDK_FALLTHROUGH;
+ case 7: /* 5/0/2.1ch front */
pPce->NumFrontChannelElements += 1;
pPce->FrontElementIsCpe[2] = 1;
pPce->NumChannels += 2;
pPce->NumEffectiveChannels += 2;
+ FDK_FALLTHROUGH;
case 6: /* 3/0/2.1ch */
pPce->NumLfeChannelElements += 1;
pPce->NumChannels += 1;
+ FDK_FALLTHROUGH;
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;
+ FDK_FALLTHROUGH;
case 3: /* 3/0/0.0ch */
pPce->NumFrontChannelElements += 1;
pPce->FrontElementIsCpe[1] = 1;
pPce->NumChannels += 2;
pPce->NumEffectiveChannels += 2;
+ FDK_FALLTHROUGH;
case 1: /* 1/0/0.0ch */
pPce->NumFrontChannelElements += 1;
pPce->FrontElementIsCpe[0] = 0;
@@ -713,6 +719,7 @@ int CProgramConfig_LookupElement(CProgramConfig *pPce, UINT channelConfig,
switch (elType) {
case ID_CPE:
isCpe = 1;
+ FDK_FALLTHROUGH;
case ID_SCE:
/* search in front channels */
for (i = 0; i < pPce->NumFrontChannelElements; i++) {
@@ -1293,7 +1300,11 @@ static INT ld_sbr_header(CSAudioSpecificConfig *asc, const INT dsFactor,
/* read elements of the passed channel_configuration until there is ID_NONE */
while ((element = channel_configuration_array[channelConfiguration][j]) !=
ID_NONE) {
- if (element == ID_SCE || element == ID_CPE) {
+ /* Setup LFE element for upsampling too. This is essential especially for
+ * channel configs where the LFE element is not at the last position for
+ * example in channel config 13 or 14. It leads to memory leaks if the setup
+ * of the LFE element would be done later in the core. */
+ if (element == ID_SCE || element == ID_CPE || element == ID_LFE) {
error |= cb->cbSbr(
cb->cbSbrData, hBs, asc->m_samplingFrequency / dsFactor,
asc->m_extensionSamplingFrequency / dsFactor,
@@ -1402,17 +1413,23 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
esc->m_useLdQmfTimeAlign = 1;
if (cb->cbSsc != NULL) {
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
- cb->cbSscData, hBs, asc->m_aot, asc->m_extensionSamplingFrequency,
+ cb->cbSscData, hBs, asc->m_aot,
+ asc->m_samplingFrequency << esc->m_sbrSamplingRate,
+ asc->m_samplesPerFrame << esc->m_sbrSamplingRate,
1, /* stereoConfigIndex */
-1, /* nTimeSlots: read from bitstream */
eldExtLen, asc->configMode, &asc->SacConfigChanged);
if (ErrorStatus != TRANSPORTDEC_OK) {
return TRANSPORTDEC_PARSE_ERROR;
}
+ if (esc->m_downscaledSamplingFrequency != asc->m_samplingFrequency) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* ELDv2 w/ ELD downscaled
+ mode not allowed */
+ }
break;
}
- /* fall-through */
+ FDK_FALLTHROUGH;
default:
for (cnt = 0; cnt < eldExtLen; cnt++) {
FDKreadBits(hBs, 8);
@@ -1430,6 +1447,10 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
if (downscale_fill_nibble != 0x0) {
return TRANSPORTDEC_PARSE_ERROR;
}
+ if (esc->m_useLdQmfTimeAlign == 1) {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* ELDv2 w/ ELD downscaled
+ mode not allowed */
+ }
break;
}
}
@@ -1793,9 +1814,16 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
if (usc->element[i].m_stereoConfigIndex > 0) {
if (cb->cbSsc != NULL) {
+ int samplesPerFrame = asc->m_samplesPerFrame;
+
+ if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2;
+ if (usc->m_sbrRatioIndex == 2)
+ samplesPerFrame = (samplesPerFrame * 8) / 3;
+ if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1;
+
/* Mps212Config() ISO/IEC FDIS 23003-3 */
if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot,
- asc->m_extensionSamplingFrequency,
+ asc->m_extensionSamplingFrequency, samplesPerFrame,
usc->element[i].m_stereoConfigIndex,
usc->m_coreSbrFrameLengthIndex,
0, /* don't know the length */
@@ -2022,6 +2050,7 @@ static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(
break;
case ASCEXT_MPS: /* 0x76a */
if (self->m_extensionAudioObjectType == AOT_MPEGS) break;
+ FDK_FALLTHROUGH;
case ASCEXT_LDMPS: /* 0x7cc */
if ((ascExtId == ASCEXT_LDMPS) &&
(self->m_extensionAudioObjectType == AOT_LD_MPEGS))
@@ -2102,7 +2131,9 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
self->m_aot = getAOT(bs);
self->m_samplingFrequency =
getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
- if (self->m_samplingFrequency <= 0) {
+ if (self->m_samplingFrequency <= 0 ||
+ (self->m_samplingFrequency > 96000 && self->m_aot != 39) ||
+ self->m_samplingFrequency > 4 * 96000) {
return TRANSPORTDEC_PARSE_ERROR;
}
@@ -2159,8 +2190,9 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
case AOT_MPEGS:
if (cb->cbSsc != NULL) {
if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency,
- 1, -1, /* nTimeSlots: read from bitstream */
- 0, /* don't know the length */
+ self->m_samplesPerFrame, 1,
+ -1, /* nTimeSlots: read from bitstream */
+ 0, /* don't know the length */
self->configMode, &self->SacConfigChanged)) {
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
@@ -2343,10 +2375,17 @@ static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig(
/*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2);
if (usc->element[elemIdx].m_stereoConfigIndex > 0) {
if (cb->cbSsc != NULL) {
+ int samplesPerFrame = asc->m_samplesPerFrame;
+
+ if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2;
+ if (usc->m_sbrRatioIndex == 2)
+ samplesPerFrame = (samplesPerFrame * 8) / 3;
+ if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1;
+
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
cb->cbSscData, hBs,
AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */
- asc->m_extensionSamplingFrequency,
+ asc->m_extensionSamplingFrequency, samplesPerFrame,
usc->element[elemIdx].m_stereoConfigIndex,
usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */
asc->configMode, &asc->SacConfigChanged);
@@ -2496,6 +2535,7 @@ TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
switch (audioMode) {
case 1: /* parametric stereo */
self->m_psPresentFlag = 1;
+ FDK_FALLTHROUGH;
case 0: /* mono */
self->m_channelConfiguration = 1;
break;