AAC Decoder: support 6.1/7.1 decoded as 5.1
- Add 6.1 and 7.1 channel support including downmixer. Per default the decoder creates a 5.1 channel output for all streams with more than six encoded channels. Modified file(s): libPCMutils/include/pcmutils_lib.h libPCMutils/src/pcmutils_lib.cpp libAACdec/include/aacdecoder_lib.h libAACdec/src/aac_rom.h libAACdec/src/aacdecoder.cpp libAACdec/src/aac_ram.cpp libAACdec/src/aacdec_drc.cpp libAACdec/src/aacdecoder_lib.cpp libAACdec/src/aac_rom.cpp libAACdec/src/aacdecoder.h libSBRdec/include/sbrdecoder.h libSBRdec/src/sbrdec_drc.h libSBRdec/src/sbrdecoder.cpp libSBRdec/src/sbr_ram.cpp libSBRdec/src/sbr_ram.h libMpegTPDec/include/tp_data.h libMpegTPDec/include/tpdec_lib.h libMpegTPDec/src/version libMpegTPDec/src/tpdec_asc.cpp libMpegTPEnc/include/tp_data.h libMpegTPEnc/src/version libSYS/include/FDK_audio.h libSYS/src/genericStds.cpp - Fix error concealment modules fade-out/in mechanism. Modified file(s): libAACdec/src/conceal.cpp Bug 9428126 Change-Id: I3230bd2072314b730911cd7ec1740e290cb1d254
This commit is contained in:
parent
fa3eba1644
commit
47c680c622
File diff suppressed because one or more lines are too long
@ -430,21 +430,58 @@ typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
AAC_PCM_OUTPUT_INTERLEAVED = 0x0000, /*!< PCM output mode (1: interleaved (default); 0: not interleaved). */
|
||||
AAC_PCM_OUTPUT_CHANNELS = 0x0001, /*!< Number of PCM output channels (if different from encoded audio channels, downmixing or
|
||||
upmixing is applied). \n
|
||||
-1: Disable up-/downmixing. The decoder output contains the same number of channels as the
|
||||
encoded bitstream. \n
|
||||
1: The decoder performs a mono matrix mix-down if the encoded audio channels are greater
|
||||
than one. Thus it ouputs always exact one channel. \n
|
||||
2: The decoder performs a stereo matrix mix-down if the encoded audio channels are greater
|
||||
than two. If the encoded audio channels are smaller than two the decoder duplicates the
|
||||
output. Thus it ouputs always exact two channels. \n */
|
||||
AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE = 0x0002, /*!< Defines how the decoder processes two channel signals:
|
||||
0: Leave both signals as they are (default).
|
||||
1: Create a dual mono output signal from channel 1.
|
||||
2: Create a dual mono output signal from channel 2.
|
||||
AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE = 0x0002, /*!< Defines how the decoder processes two channel signals: \n
|
||||
0: Leave both signals as they are (default). \n
|
||||
1: Create a dual mono output signal from channel 1. \n
|
||||
2: Create a dual mono output signal from channel 2. \n
|
||||
3: Create a dual mono output signal by mixing both channels (L' = R' = 0.5*Ch1 + 0.5*Ch2). */
|
||||
AAC_PCM_OUTPUT_CHANNEL_MAPPING = 0x0003, /*!< Output buffer channel ordering. 0: MPEG PCE style order, 1: WAV file channel order (default). */
|
||||
AAC_PCM_MIN_OUTPUT_CHANNELS = 0x0011, /*!< Minimum number of PCM output channels. If higher than the number of encoded audio channels,
|
||||
a simple channel extension is applied. \n
|
||||
-1, 0: Disable channel extenstion feature. The decoder output contains the same number of
|
||||
channels as the encoded bitstream. \n
|
||||
1: This value is currently needed only together with the mix-down feature. See
|
||||
::AAC_PCM_MAX_OUTPUT_CHANNELS and note 2 below. \n
|
||||
2: Encoded mono signals will be duplicated to achieve a 2/0/0.0 channel output
|
||||
configuration. \n
|
||||
6: The decoder trys to reorder encoded signals with less than six channels to achieve
|
||||
a 3/0/2.1 channel output signal. Missing channels will be filled with a zero signal.
|
||||
If reordering is not possible the empty channels will simply be appended. Only
|
||||
available if instance is configured to support multichannel output. \n
|
||||
8: The decoder trys to reorder encoded signals with less than eight channels to
|
||||
achieve a 3/0/4.1 channel output signal. Missing channels will be filled with a
|
||||
zero signal. If reordering is not possible the empty channels will simply be
|
||||
appended. Only available if instance is configured to support multichannel output.\n
|
||||
NOTE: \n
|
||||
1. The channel signalling (CStreamInfo::pChannelType and CStreamInfo::pChannelIndices)
|
||||
will not be modified. Added empty channels will be signalled with channel type
|
||||
AUDIO_CHANNEL_TYPE::ACT_NONE. \n
|
||||
2. If the parameter value is greater than that of ::AAC_PCM_MAX_OUTPUT_CHANNELS both will
|
||||
be set to the same value. \n
|
||||
3. This parameter does not affect MPEG Surround processing. */
|
||||
AAC_PCM_MAX_OUTPUT_CHANNELS = 0x0012, /*!< Maximum number of PCM output channels. If lower than the number of encoded audio channels,
|
||||
downmixing is applied accordingly. If dedicated metadata is available in the stream it
|
||||
will be used to achieve better mixing results. \n
|
||||
-1, 0: Disable downmixing feature. The decoder output contains the same number of channels
|
||||
as the encoded bitstream. \n
|
||||
1: All encoded audio configurations with more than one channel will be mixed down to
|
||||
one mono output signal. \n
|
||||
2: The decoder performs a stereo mix-down if the number encoded audio channels is
|
||||
greater than two. \n
|
||||
6: If the number of encoded audio channels is greater than six the decoder performs a
|
||||
mix-down to meet the target output configuration of 3/0/2.1 channels. Only
|
||||
available if instance is configured to support multichannel output. \n
|
||||
8: This value is currently needed only together with the channel extension feature.
|
||||
See ::AAC_PCM_MIN_OUTPUT_CHANNELS and note 2 below. Only available if instance is
|
||||
configured to support multichannel output. \n
|
||||
NOTE: \n
|
||||
1. Down-mixing of any seven or eight channel configuration not defined in ISO/IEC 14496-3
|
||||
PDAM 4 is not supported by this software version. \n
|
||||
2. If the parameter value is greater than zero but smaller than ::AAC_PCM_MIN_OUTPUT_CHANNELS
|
||||
both will be set to same value. \n
|
||||
3. The operating mode of the MPEG Surround module will be set accordingly. \n
|
||||
4. Setting this param with any value will disable the binaural processing of the MPEG
|
||||
Surround module (::AAC_MPEGS_BINAURAL_ENABLE=0). */
|
||||
|
||||
AAC_CONCEAL_METHOD = 0x0100, /*!< Error concealment: Processing method. \n
|
||||
0: Spectral muting. \n
|
||||
|
@ -108,15 +108,15 @@ C_ALLOC_MEM(AacDecoder, AAC_DECODER_INSTANCE, 1)
|
||||
/*! The structure CAacDecoderStaticChannelInfo contains the static sideinfo which is needed
|
||||
for the decoding of one aac channel. <br>
|
||||
Dimension: #AacDecoderChannels */
|
||||
C_ALLOC_MEM2(AacDecoderStaticChannelInfo, CAacDecoderStaticChannelInfo, 1, (6))
|
||||
C_ALLOC_MEM2(AacDecoderStaticChannelInfo, CAacDecoderStaticChannelInfo, 1, (8))
|
||||
|
||||
/*! The structure CAacDecoderChannelInfo contains the dynamic sideinfo which is needed
|
||||
for the decoding of one aac channel. <br>
|
||||
Dimension: #AacDecoderChannels */
|
||||
C_ALLOC_MEM2(AacDecoderChannelInfo, CAacDecoderChannelInfo, 1, (6))
|
||||
C_AALLOC_MEM2(AacDecoderChannelInfo, CAacDecoderChannelInfo, 1, (8))
|
||||
|
||||
/*! Overlap buffer */
|
||||
C_ALLOC_MEM2(OverlapBuffer, FIXP_DBL, OverlapBufferSize, (6))
|
||||
C_ALLOC_MEM2(OverlapBuffer, FIXP_DBL, OverlapBufferSize, (8))
|
||||
|
||||
C_ALLOC_MEM(DrcInfo, CDrcInfo, 1)
|
||||
|
||||
@ -128,7 +128,7 @@ C_ALLOC_MEM(DrcInfo, CDrcInfo, 1)
|
||||
Dynamic memory areas, might be reused in other algorithm sections,
|
||||
e.g. the sbr decoder
|
||||
*/
|
||||
C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((6)*1024), SECT_DATA_L2, WORKBUFFER2_TAG)
|
||||
C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8)*1024), SECT_DATA_L2, WORKBUFFER2_TAG)
|
||||
|
||||
|
||||
C_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1, 1, SECT_DATA_L1, WORKBUFFER1_TAG)
|
||||
|
@ -1777,42 +1777,62 @@ const FIXP_TCC FDKaacDec_tnsCoeff4 [16] =
|
||||
};
|
||||
|
||||
/* MPEG like mapping (no change). */
|
||||
const UCHAR channelMappingTablePassthrough[8][8] =
|
||||
const UCHAR channelMappingTablePassthrough[15][8] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* fallback */
|
||||
{ 0, 1,255,255,255,255,255,255}, /* mono / PS */
|
||||
{ 0, 1,255,255,255,255,255,255}, /* stereo */
|
||||
{ 0, 1, 2,255,255,255,255,255}, /* 3ch */
|
||||
{ 0, 1, 2, 3,255,255,255,255}, /* 4ch */
|
||||
{ 0, 1, 2, 3, 4,255,255,255}, /* 5ch */
|
||||
{ 0, 1, 2, 3, 4, 5,255,255}, /* 5.1ch */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* 7ch */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7} /* 7.1ch */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* 7.1 front */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
|
||||
{ 0, 1, 2, 3, 4, 5, 6,255}, /* 6.1ch */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* 7.1 rear */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7} /* 7.1 top */
|
||||
};
|
||||
|
||||
/* WAV file like mapping (from MPEG mapping). */
|
||||
const UCHAR channelMappingTableWAV[8][8] =
|
||||
const UCHAR channelMappingTableWAV[15][8] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* fallback */
|
||||
{ 0, 1,255,255,255,255,255,255}, /* mono / PS */
|
||||
{ 0, 1,255,255,255,255,255,255}, /* stereo */
|
||||
{ 2, 0, 1,255,255,255,255,255}, /* 3ch */
|
||||
{ 2, 0, 1, 3,255,255,255,255}, /* 4ch */
|
||||
{ 2, 0, 1, 3, 4,255,255,255}, /* 5ch */
|
||||
{ 2, 0, 1, 4, 5, 3,255,255}, /* 5.1ch */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* 7ch */
|
||||
{ 2, 0, 1, 6, 7, 4, 5, 3} /* 7.1ch */
|
||||
{ 2, 6, 7, 0, 1, 4, 5, 3}, /* 7.1 front */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
|
||||
{ 2, 0, 1, 4, 5, 6, 3,255}, /* 6.1ch */
|
||||
{ 2, 0, 1, 6, 7, 4, 5, 3}, /* 7.1 rear */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */
|
||||
{ 2, 0, 1, 4, 5, 3, 6, 7} /* 7.1 top */
|
||||
};
|
||||
|
||||
/* Lookup tables for elements in ER bitstream */
|
||||
const MP4_ELEMENT_ID elementsTab[8][7] =
|
||||
const MP4_ELEMENT_ID elementsTab[15][7] =
|
||||
{
|
||||
{ID_SCE, ID_EXT, ID_END, ID_NONE, ID_NONE,ID_NONE,ID_NONE }, /* 1 channel */
|
||||
{ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE,ID_NONE,ID_NONE } /* 2 channels */
|
||||
,
|
||||
{ID_SCE, ID_CPE, ID_EXT, ID_END, ID_NONE,ID_NONE,ID_NONE }, /* 3 channels */
|
||||
{ID_SCE, ID_CPE, ID_SCE, ID_EXT, ID_END, ID_NONE,ID_NONE }, /* 4 channels */
|
||||
{ID_SCE, ID_CPE, ID_CPE, ID_EXT, ID_END, ID_NONE,ID_NONE }, /* 5 channels */
|
||||
{ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END, ID_NONE }, /* 6 channels */
|
||||
{ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END} /* 8 channels */
|
||||
/* 1 */ { ID_SCE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* 1 channel */
|
||||
/* 2 */ { ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE, ID_NONE } /* 2 channels */
|
||||
/* 3 */ ,{ ID_SCE, ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE }, /* 3 channels */
|
||||
/* 4 */ { ID_SCE, ID_CPE, ID_SCE, ID_EXT, ID_END, ID_NONE, ID_NONE }, /* 4 channels */
|
||||
/* 5 */ { ID_SCE, ID_CPE, ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE }, /* 5 channels */
|
||||
/* 6 */ { ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END, ID_NONE } /* 6 channels */
|
||||
/* 7 */ ,{ ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END }, /* 8 channels */
|
||||
/* 8 */ { ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* reserved */
|
||||
/* 9 */ { ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* reserved */
|
||||
/* 10 */ { ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* reserved */
|
||||
/* 11 */ { ID_SCE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_EXT, ID_END }, /* 7 channels */
|
||||
/* 12 */ { ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END }, /* 8 channels */
|
||||
/* 13 */ { ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE }, /* reserved */
|
||||
/* 14 */ { ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_CPE, ID_EXT, ID_END } /* 8 channels */
|
||||
};
|
||||
|
||||
/*! Random sign bit used for concealment
|
||||
|
@ -177,11 +177,12 @@ extern const USHORT randomSign[AAC_NF_NO_RANDOM_VAL/16];
|
||||
extern const FIXP_DBL pow2_div24minus1[47];
|
||||
extern const int offsetTab[2][16];
|
||||
|
||||
/* Channel mapping indices for time domain I/O. First dimension is channel count-1. */
|
||||
extern const UCHAR channelMappingTablePassthrough[8][8];
|
||||
extern const UCHAR channelMappingTableWAV[8][8];
|
||||
/* Channel mapping indices for time domain I/O.
|
||||
The first dimension is the channel configuration index. */
|
||||
extern const UCHAR channelMappingTablePassthrough[15][8];
|
||||
extern const UCHAR channelMappingTableWAV[15][8];
|
||||
|
||||
/* Lookup tables for elements in ER bitstream */
|
||||
extern const MP4_ELEMENT_ID elementsTab[8][7];
|
||||
extern const MP4_ELEMENT_ID elementsTab[15][7];
|
||||
|
||||
#endif /* #ifndef AAC_ROM_H */
|
||||
|
@ -539,7 +539,7 @@ static int aacDecoder_drcReadCompression (
|
||||
UINT payloadPosition )
|
||||
{
|
||||
int bitCnt = 0;
|
||||
int dmxLevelsPresent, compressionPresent;
|
||||
int dmxLevelsPresent, extensionPresent, compressionPresent;
|
||||
int coarseGrainTcPresent, fineGrainTcPresent;
|
||||
|
||||
/* Move to the beginning of the DRC payload field */
|
||||
@ -562,7 +562,8 @@ static int aacDecoder_drcReadCompression (
|
||||
}
|
||||
FDKreadBits(bs, 2); /* dolby_surround_mode */
|
||||
FDKreadBits(bs, 2); /* presentation_mode */
|
||||
if (FDKreadBits(bs, 2) != 0) { /* reserved, set to 0 */
|
||||
FDKreadBits(bs, 1); /* stereo_downmix_mode */
|
||||
if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -571,9 +572,7 @@ static int aacDecoder_drcReadCompression (
|
||||
return 0;
|
||||
}
|
||||
dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
|
||||
if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */
|
||||
return 0;
|
||||
}
|
||||
extensionPresent = FDKreadBits(bs, 1); /* ancillary_data_extension_status; */
|
||||
compressionPresent = FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
|
||||
coarseGrainTcPresent = FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
|
||||
fineGrainTcPresent = FDKreadBits(bs, 1); /* fine_grain_timecode_status */
|
||||
@ -631,6 +630,19 @@ static int aacDecoder_drcReadCompression (
|
||||
bitCnt += 16;
|
||||
}
|
||||
|
||||
/* Read extension just to get the right amount of bits. */
|
||||
if (extensionPresent) {
|
||||
int extBits = 8;
|
||||
|
||||
FDKreadBits(bs, 1); /* reserved, set to 0 */
|
||||
if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_levels_status */
|
||||
if (FDKreadBits(bs, 1)) extBits += 16; /* ext_downmixing_global_gains_status */
|
||||
if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_lfe_level_status */
|
||||
|
||||
FDKpushFor(bs, extBits - 4); /* skip the extension payload remainder. */
|
||||
bitCnt += extBits;
|
||||
}
|
||||
|
||||
return (bitCnt);
|
||||
}
|
||||
|
||||
|
@ -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,20 +378,30 @@ 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 );
|
||||
|
||||
if (readBits != dataBits) {
|
||||
/* Move to the end again. */
|
||||
FDKpushBiDirectional(bs, FDKgetValidBits(bs)-dataStart+dataBits);
|
||||
}
|
||||
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));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -774,7 +790,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 +867,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 +891,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 +934,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 +1118,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 +1142,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;
|
||||
}
|
||||
}
|
||||
@ -1378,10 +1401,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 +1422,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 +1440,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 */
|
||||
@ -1632,6 +1630,23 @@ 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
|
||||
*/
|
||||
@ -1663,10 +1678,10 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
@ -1746,8 +1761,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
|
||||
/* 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 +1772,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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,22 +176,23 @@ struct AAC_DECODER_INSTANCE {
|
||||
|
||||
UINT flags; /*!< Flags for internal decoder use. DO NOT USE self::streaminfo::flags ! */
|
||||
|
||||
MP4_ELEMENT_ID elements[7]; /*!< Table where the element Id's are listed */
|
||||
UCHAR elTags[7]; /*!< Table where the elements id Tags are listed */
|
||||
UCHAR chMapping[(6)]; /*!< Table of MPEG canonical order to bitstream channel order mapping. */
|
||||
MP4_ELEMENT_ID elements[(8)]; /*!< Table where the element Id's are listed */
|
||||
UCHAR elTags[(8)]; /*!< Table where the elements id Tags are listed */
|
||||
UCHAR chMapping[(8)]; /*!< Table of MPEG canonical order to bitstream channel order mapping. */
|
||||
|
||||
AUDIO_CHANNEL_TYPE channelType[(6)]; /*!< Audio channel type of each output audio channel (from 0 upto numChannels). */
|
||||
UCHAR channelIndices[(6)]; /*!< Audio channel index for each output audio channel (from 0 upto numChannels). */
|
||||
AUDIO_CHANNEL_TYPE channelType[(8)]; /*!< Audio channel type of each output audio channel (from 0 upto numChannels). */
|
||||
UCHAR channelIndices[(8)]; /*!< Audio channel index for each output audio channel (from 0 upto numChannels). */
|
||||
/* See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a program_config_element() */
|
||||
|
||||
|
||||
const UCHAR (*channelOutputMapping)[8]; /*!< Table for MPEG canonical order to output channel order mapping. */
|
||||
|
||||
UCHAR chMapIndex; /*!< Index to access one line of the channelOutputMapping table. This is required
|
||||
because not all 8 channel configurations have the same output mapping. */
|
||||
|
||||
CProgramConfig pce;
|
||||
CStreamInfo streamInfo; /*!< pointer to StreamInfo data (read from the bitstream) */
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo[(6)]; /*!< Temporal channel memory */
|
||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[(6)]; /*!< Persistent channel memory */
|
||||
CAacDecoderChannelInfo *pAacDecoderChannelInfo[(8)]; /*!< Temporal channel memory */
|
||||
CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */
|
||||
|
||||
CAacDecoderCommonData aacCommonData; /*!< Temporal shared data for all channels hooked into pAacDecoderChannelInfo */
|
||||
|
||||
|
@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
|
||||
/* Decoder library info */
|
||||
#define AACDECODER_LIB_VL0 2
|
||||
#define AACDECODER_LIB_VL1 5
|
||||
#define AACDECODER_LIB_VL2 5
|
||||
#define AACDECODER_LIB_VL2 6
|
||||
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
|
||||
#define AACDECODER_LIB_BUILD_DATE __DATE__
|
||||
#define AACDECODER_LIB_BUILD_TIME __TIME__
|
||||
@ -420,8 +420,8 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode
|
||||
self->outputInterleaved = value;
|
||||
break;
|
||||
|
||||
case AAC_PCM_OUTPUT_CHANNELS:
|
||||
if (value < -1 || value > (6)) {
|
||||
case AAC_PCM_MIN_OUTPUT_CHANNELS:
|
||||
if (value < -1 || value > (8)) {
|
||||
return AAC_DEC_SET_PARAM_FAIL;
|
||||
}
|
||||
{
|
||||
@ -429,7 +429,30 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode
|
||||
|
||||
err = pcmDmx_SetParam (
|
||||
hPcmDmx,
|
||||
NUMBER_OF_OUTPUT_CHANNELS,
|
||||
MIN_NUMBER_OF_OUTPUT_CHANNELS,
|
||||
value );
|
||||
|
||||
switch (err) {
|
||||
case PCMDMX_OK:
|
||||
break;
|
||||
case PCMDMX_INVALID_HANDLE:
|
||||
return AAC_DEC_INVALID_HANDLE;
|
||||
default:
|
||||
return AAC_DEC_SET_PARAM_FAIL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AAC_PCM_MAX_OUTPUT_CHANNELS:
|
||||
if (value < -1 || value > (8)) {
|
||||
return AAC_DEC_SET_PARAM_FAIL;
|
||||
}
|
||||
{
|
||||
PCMDMX_ERROR err;
|
||||
|
||||
err = pcmDmx_SetParam (
|
||||
hPcmDmx,
|
||||
MAX_NUMBER_OF_OUTPUT_CHANNELS,
|
||||
value );
|
||||
|
||||
switch (err) {
|
||||
@ -449,7 +472,7 @@ aacDecoder_SetParam ( const HANDLE_AACDECODER self, /*!< Handle of the decode
|
||||
|
||||
err = pcmDmx_SetParam (
|
||||
hPcmDmx,
|
||||
DUAL_CHANNEL_DOWNMIX_MODE,
|
||||
DMX_DUAL_CHANNEL_MODE,
|
||||
value );
|
||||
|
||||
switch (err) {
|
||||
@ -825,6 +848,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
||||
if (self->sbrEnabled)
|
||||
{
|
||||
SBR_ERROR sbrError = SBRDEC_OK;
|
||||
int chOutMapIdx = ((self->chMapIndex==0) && (self->streamInfo.numChannels<7)) ? self->streamInfo.numChannels : self->chMapIndex;
|
||||
|
||||
/* set params */
|
||||
sbrDecoder_SetParam ( self->hSbrDecoder,
|
||||
@ -838,7 +862,16 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
||||
(self->flags & AC_LD_MPS) ? 1 : 0 );
|
||||
}
|
||||
|
||||
{
|
||||
PCMDMX_ERROR dmxErr;
|
||||
INT maxOutCh = 0;
|
||||
|
||||
dmxErr = pcmDmx_GetParam(self->hPcmUtils, MAX_NUMBER_OF_OUTPUT_CHANNELS, &maxOutCh);
|
||||
if ( (dmxErr == PCMDMX_OK) && (maxOutCh == 1) ) {
|
||||
/* Disable PS processing if we have to create a mono output signal. */
|
||||
self->psPossible = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* apply SBR processing */
|
||||
@ -846,7 +879,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
||||
pTimeData,
|
||||
&self->streamInfo.numChannels,
|
||||
&self->streamInfo.sampleRate,
|
||||
self->channelOutputMapping[self->streamInfo.numChannels-1],
|
||||
self->channelOutputMapping[chOutMapIdx],
|
||||
interleaved,
|
||||
self->frameOK,
|
||||
&self->psPossible);
|
||||
@ -870,19 +903,19 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
||||
self->channelType[1] = ACT_FRONT;
|
||||
self->channelIndices[0] = 0;
|
||||
self->channelIndices[1] = 1;
|
||||
} else {
|
||||
self->flags &= ~AC_PS_PRESENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
PCMDMX_ERROR dmxErr = PCMDMX_OK;
|
||||
if ( flags & (AACDEC_INTR | AACDEC_CLRHIST) ) {
|
||||
/* delete data from the past (e.g. mixdown coeficients) */
|
||||
pcmDmx_Reset( self->hPcmUtils, PCMDMX_RESET_BS_DATA );
|
||||
}
|
||||
/* do PCM post processing */
|
||||
pcmDmx_ApplyFrame (
|
||||
dmxErr = pcmDmx_ApplyFrame (
|
||||
self->hPcmUtils,
|
||||
pTimeData,
|
||||
self->streamInfo.frameSize,
|
||||
@ -890,9 +923,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
||||
interleaved,
|
||||
self->channelType,
|
||||
self->channelIndices,
|
||||
self->channelOutputMapping
|
||||
self->channelOutputMapping,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (dmxErr == PCMDMX_INVALID_MODE) {
|
||||
/* Announce the framework that the current combination of channel configuration and downmix
|
||||
* settings are not know to produce a predictable behavior and thus maybe produce strange output. */
|
||||
ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Signal interruption to take effect in next frame. */
|
||||
|
@ -762,7 +762,6 @@ int
|
||||
CConcealment_UpdateState( hConcealmentInfo,
|
||||
frameOk );
|
||||
|
||||
if ( !frameOk )
|
||||
{
|
||||
/* Create data for signal rendering according to the selected concealment method and decoder operating mode. */
|
||||
|
||||
@ -775,11 +774,13 @@ int
|
||||
{
|
||||
default:
|
||||
case ConcealMethodMute:
|
||||
/* Mute spectral data in case of errors */
|
||||
FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
|
||||
/* Set last window shape */
|
||||
pAacDecoderChannelInfo->icsInfo.WindowShape = hConcealmentInfo->windowShape;
|
||||
appliedProcessing = 1;
|
||||
if (!frameOk) {
|
||||
/* Mute spectral data in case of errors */
|
||||
FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
|
||||
/* Set last window shape */
|
||||
pAacDecoderChannelInfo->icsInfo.WindowShape = hConcealmentInfo->windowShape;
|
||||
appliedProcessing = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case ConcealMethodNoise:
|
||||
@ -801,7 +802,7 @@ int
|
||||
pSamplingRateInfo,
|
||||
samplesPerFrame,
|
||||
0, /* don't use tonal improvement */
|
||||
0);
|
||||
frameOk);
|
||||
break;
|
||||
|
||||
}
|
||||
|
@ -146,12 +146,15 @@ typedef struct
|
||||
|
||||
UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR FrontElementHeightInfo[PC_FSB_CHANNELS_MAX];
|
||||
|
||||
UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR SideElementHeightInfo[PC_FSB_CHANNELS_MAX];
|
||||
|
||||
UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR BackElementHeightInfo[PC_FSB_CHANNELS_MAX];
|
||||
|
||||
UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX];
|
||||
|
||||
@ -324,16 +327,23 @@ int getSamplingRateIndex( UINT samplingRate )
|
||||
*/
|
||||
static inline int getNumberOfTotalChannels(int channelConfig)
|
||||
{
|
||||
if (channelConfig > 0 && channelConfig < 8)
|
||||
return (channelConfig == 7)?8:channelConfig;
|
||||
else
|
||||
switch (channelConfig) {
|
||||
case 1: case 2: case 3:
|
||||
case 4: case 5: case 6:
|
||||
return channelConfig;
|
||||
case 7: case 12: case 14:
|
||||
return 8;
|
||||
case 11:
|
||||
return 7;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
int getNumberOfEffectiveChannels(const int channelConfig)
|
||||
{
|
||||
const int n[] = {0,1,2,3,4,5,5,7};
|
||||
{ /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */
|
||||
const int n[] = {0,1,2,3,4,5,5,7,0,0, 0, 6, 7, 0, 7, 0};
|
||||
return n[channelConfig];
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,7 @@ typedef enum {
|
||||
#define PC_ASSOCDATA_MAX 8
|
||||
#define PC_CCEL_MAX 16 /* CC elements */
|
||||
#define PC_COMMENTLENGTH 256
|
||||
#define PC_NUM_HEIGHT_LAYER 3
|
||||
|
||||
|
||||
/*!
|
||||
@ -239,14 +240,20 @@ int CProgramConfig_LookupElement(
|
||||
);
|
||||
|
||||
/**
|
||||
* \brief Get table of elements in canonical order.
|
||||
* \param pPce A valid program config structure.
|
||||
* \param table An array where the element IDs are stored.
|
||||
* \return Total element count including all SCE, CPE and LFE.
|
||||
* \brief Get table of elements in canonical order from a
|
||||
* give program config field.
|
||||
* \param pPce A valid program config structure.
|
||||
* \param table An array where the element IDs are stored.
|
||||
* \param elListSize The length of the table array.
|
||||
* \param pChMapIdx Pointer to a field receiving the corresponding
|
||||
* implicit channel configuration index of the given
|
||||
* PCE. If none can be found it receives the value 0.
|
||||
* \return Total element count including all SCE, CPE and LFE.
|
||||
*/
|
||||
int CProgramConfig_GetElementTable( const CProgramConfig *pPce,
|
||||
MP4_ELEMENT_ID table[],
|
||||
const INT elListSize );
|
||||
const INT elListSize,
|
||||
UCHAR *pChMapIdx );
|
||||
|
||||
/**
|
||||
* \brief Initialize a given AudioSpecificConfig structure.
|
||||
|
@ -90,6 +90,9 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
#include "tpdec_lib.h"
|
||||
#include "tp_data.h"
|
||||
#ifdef TP_PCE_ENABLE
|
||||
#include "FDK_crc.h"
|
||||
#endif
|
||||
|
||||
|
||||
void CProgramConfig_Reset(CProgramConfig *pPce)
|
||||
@ -111,13 +114,75 @@ int CProgramConfig_IsValid ( const CProgramConfig *pPce )
|
||||
}
|
||||
|
||||
#ifdef TP_PCE_ENABLE
|
||||
#define PCE_HEIGHT_EXT_SYNC ( 0xAC )
|
||||
|
||||
/*
|
||||
* Read the extension for height info.
|
||||
* return 0 if successfull or -1 if the CRC failed.
|
||||
*/
|
||||
static
|
||||
int CProgramConfig_ReadHeightExt(
|
||||
CProgramConfig *pPce,
|
||||
HANDLE_FDK_BITSTREAM bs,
|
||||
int * const bytesAvailable,
|
||||
const UINT alignmentAnchor
|
||||
)
|
||||
{
|
||||
int err = 0;
|
||||
FDK_CRCINFO crcInfo; /* CRC state info */
|
||||
INT crcReg;
|
||||
FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
|
||||
crcReg = FDKcrcStartReg(&crcInfo, bs, 0);
|
||||
UINT startAnchor = FDKgetValidBits(bs);
|
||||
|
||||
FDK_ASSERT(pPce != NULL);
|
||||
FDK_ASSERT(bs != NULL);
|
||||
FDK_ASSERT(bytesAvailable != NULL);
|
||||
|
||||
if ( (startAnchor >= 24) && (*bytesAvailable >= 3)
|
||||
&& (FDKreadBits(bs,8) == PCE_HEIGHT_EXT_SYNC) )
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < pPce->NumFrontChannelElements; i++)
|
||||
{
|
||||
pPce->FrontElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
|
||||
}
|
||||
for (i=0; i < pPce->NumSideChannelElements; i++)
|
||||
{
|
||||
pPce->SideElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
|
||||
}
|
||||
for (i=0; i < pPce->NumBackChannelElements; i++)
|
||||
{
|
||||
pPce->BackElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
|
||||
}
|
||||
FDKbyteAlign(bs, alignmentAnchor);
|
||||
|
||||
FDKcrcEndReg(&crcInfo, bs, crcReg);
|
||||
if ((USHORT)FDKreadBits(bs,8) != FDKcrcGetCRC(&crcInfo)) {
|
||||
/* CRC failed */
|
||||
err = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* No valid extension data found -> restore the initial bitbuffer state */
|
||||
FDKpushBack(bs, startAnchor - FDKgetValidBits(bs));
|
||||
}
|
||||
|
||||
/* Always report the bytes read. */
|
||||
*bytesAvailable -= (startAnchor - FDKgetValidBits(bs)) >> 3;
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
void CProgramConfig_Read(
|
||||
CProgramConfig *pPce,
|
||||
HANDLE_FDK_BITSTREAM bs,
|
||||
UINT alignmentAnchor
|
||||
)
|
||||
{
|
||||
int i;
|
||||
int i, err = 0;
|
||||
int commentBytes;
|
||||
|
||||
pPce->NumEffectiveChannels = 0;
|
||||
pPce->NumChannels = 0;
|
||||
@ -190,8 +255,12 @@ void CProgramConfig_Read(
|
||||
FDKbyteAlign(bs, alignmentAnchor);
|
||||
|
||||
pPce->CommentFieldBytes = (UCHAR) FDKreadBits(bs,8);
|
||||
commentBytes = pPce->CommentFieldBytes;
|
||||
|
||||
for (i=0; i < pPce->CommentFieldBytes; i++)
|
||||
/* Search for height info extension and read it if available */
|
||||
err = CProgramConfig_ReadHeightExt( pPce, bs, &commentBytes, alignmentAnchor );
|
||||
|
||||
for (i=0; i < commentBytes; i++)
|
||||
{
|
||||
UCHAR text;
|
||||
|
||||
@ -203,7 +272,7 @@ void CProgramConfig_Read(
|
||||
}
|
||||
}
|
||||
|
||||
pPce->isValid = 1;
|
||||
pPce->isValid = (err) ? 0 : 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -235,6 +304,10 @@ int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
|
||||
} else {
|
||||
int el, numCh1 = 0, numCh2 = 0;
|
||||
for (el = 0; el < pPce1->NumFrontChannelElements; el += 1) {
|
||||
if (pPce1->FrontElementHeightInfo[el] != pPce2->FrontElementHeightInfo[el]) {
|
||||
result = 2; /* different height info */
|
||||
break;
|
||||
}
|
||||
numCh1 += pPce1->FrontElementIsCpe[el] ? 2 : 1;
|
||||
numCh2 += pPce2->FrontElementIsCpe[el] ? 2 : 1;
|
||||
}
|
||||
@ -248,6 +321,10 @@ int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
|
||||
} else {
|
||||
int el, numCh1 = 0, numCh2 = 0;
|
||||
for (el = 0; el < pPce1->NumSideChannelElements; el += 1) {
|
||||
if (pPce1->SideElementHeightInfo[el] != pPce2->SideElementHeightInfo[el]) {
|
||||
result = 2; /* different height info */
|
||||
break;
|
||||
}
|
||||
numCh1 += pPce1->SideElementIsCpe[el] ? 2 : 1;
|
||||
numCh2 += pPce2->SideElementIsCpe[el] ? 2 : 1;
|
||||
}
|
||||
@ -261,6 +338,10 @@ int CProgramConfig_Compare ( const CProgramConfig * const pPce1,
|
||||
} else {
|
||||
int el, numCh1 = 0, numCh2 = 0;
|
||||
for (el = 0; el < pPce1->NumBackChannelElements; el += 1) {
|
||||
if (pPce1->BackElementHeightInfo[el] != pPce2->BackElementHeightInfo[el]) {
|
||||
result = 2; /* different height info */
|
||||
break;
|
||||
}
|
||||
numCh1 += pPce1->BackElementIsCpe[el] ? 2 : 1;
|
||||
numCh2 += pPce2->BackElementIsCpe[el] ? 2 : 1;
|
||||
}
|
||||
@ -290,6 +371,44 @@ void CProgramConfig_GetDefault( CProgramConfig *pPce,
|
||||
|
||||
switch (channelConfig) {
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case 32: /* 7.1 side channel configuration as defined in FDK_audio.h */
|
||||
pPce->NumFrontChannelElements = 2;
|
||||
pPce->FrontElementIsCpe[0] = 0;
|
||||
pPce->FrontElementIsCpe[1] = 1;
|
||||
pPce->NumSideChannelElements = 1;
|
||||
pPce->SideElementIsCpe[0] = 1;
|
||||
pPce->NumBackChannelElements = 1;
|
||||
pPce->BackElementIsCpe[0] = 1;
|
||||
pPce->NumLfeChannelElements = 1;
|
||||
pPce->NumChannels = 8;
|
||||
pPce->NumEffectiveChannels = 7;
|
||||
pPce->isValid = 1;
|
||||
break;
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
case 12: /* 3/0/4.1ch surround back */
|
||||
pPce->BackElementIsCpe[1] = 1;
|
||||
pPce->NumChannels += 1;
|
||||
pPce->NumEffectiveChannels += 1;
|
||||
case 11: /* 3/0/3.1ch */
|
||||
pPce->NumFrontChannelElements += 2;
|
||||
pPce->FrontElementIsCpe[0] = 0;
|
||||
pPce->FrontElementIsCpe[1] = 1;
|
||||
pPce->NumBackChannelElements += 2;
|
||||
pPce->BackElementIsCpe[0] = 1;
|
||||
pPce->BackElementIsCpe[1] += 0;
|
||||
pPce->NumLfeChannelElements += 1;
|
||||
pPce->NumChannels += 7;
|
||||
pPce->NumEffectiveChannels += 6;
|
||||
pPce->isValid = 1;
|
||||
break;
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
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 */
|
||||
pPce->NumFrontChannelElements += 1;
|
||||
pPce->FrontElementIsCpe[2] = 1;
|
||||
pPce->NumChannels += 2;
|
||||
pPce->NumEffectiveChannels += 2;
|
||||
case 6: /* 3/0/2.1ch */
|
||||
pPce->NumLfeChannelElements += 1;
|
||||
pPce->NumChannels += 1;
|
||||
@ -348,10 +467,11 @@ void CProgramConfig_GetDefault( CProgramConfig *pPce,
|
||||
|
||||
/**
|
||||
* \brief get implicit audio channel type for given channelConfig and MPEG ordered channel index
|
||||
* \param channelConfig MPEG channelConfiguration from 1 upto 7
|
||||
* \param channelConfig MPEG channelConfiguration from 1 upto 14
|
||||
* \param index MPEG channel order index
|
||||
* \return audio channel type.
|
||||
*/
|
||||
static
|
||||
void getImplicitAudioChannelTypeAndIndex(
|
||||
AUDIO_CHANNEL_TYPE *chType,
|
||||
UCHAR *chIndex,
|
||||
@ -364,9 +484,9 @@ void getImplicitAudioChannelTypeAndIndex(
|
||||
*chIndex = index;
|
||||
} else {
|
||||
switch (channelConfig) {
|
||||
case MODE_1_2_1:
|
||||
case MODE_1_2_2:
|
||||
case MODE_1_2_2_1:
|
||||
case 4: /* SCE, CPE, SCE */
|
||||
case 5: /* SCE, CPE, CPE */
|
||||
case 6: /* SCE, CPE, CPE, LFE */
|
||||
switch (index) {
|
||||
case 3:
|
||||
case 4:
|
||||
@ -379,12 +499,12 @@ void getImplicitAudioChannelTypeAndIndex(
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MODE_1_2_2_2_1:
|
||||
case 7: /* SCE,CPE,CPE,CPE,LFE */
|
||||
switch (index) {
|
||||
case 3:
|
||||
case 4:
|
||||
*chType = ACT_SIDE;
|
||||
*chIndex = index - 3;
|
||||
*chType = ACT_FRONT;
|
||||
*chIndex = index;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
@ -397,6 +517,42 @@ void getImplicitAudioChannelTypeAndIndex(
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 11: /* SCE,CPE,CPE,SCE,LFE */
|
||||
if (index < 6) {
|
||||
*chType = ACT_BACK;
|
||||
*chIndex = index - 3;
|
||||
} else {
|
||||
*chType = ACT_LFE;
|
||||
*chIndex = 0;
|
||||
}
|
||||
break;
|
||||
case 12: /* SCE,CPE,CPE,CPE,LFE */
|
||||
if (index < 7) {
|
||||
*chType = ACT_BACK;
|
||||
*chIndex = index - 3;
|
||||
} else {
|
||||
*chType = ACT_LFE;
|
||||
*chIndex = 0;
|
||||
}
|
||||
break;
|
||||
case 14: /* SCE,CPE,CPE,LFE,CPE */
|
||||
switch (index) {
|
||||
case 3:
|
||||
case 4:
|
||||
*chType = ACT_BACK;
|
||||
*chIndex = index - 3;
|
||||
break;
|
||||
case 5:
|
||||
*chType = ACT_LFE;
|
||||
*chIndex = 0;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
*chType = ACT_FRONT_TOP;
|
||||
*chIndex = index - 6; /* handle the top layer independently */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*chType = ACT_NONE;
|
||||
break;
|
||||
@ -467,7 +623,24 @@ int CProgramConfig_LookupElement(
|
||||
else {
|
||||
/* Accept the additional channel(s), only if the tag is in the lists */
|
||||
int isCpe = 0, i;
|
||||
int cc = 0, fc = 0, sc = 0, bc = 0, lc = 0, ec = 0; /* Channel and element counters */
|
||||
/* Element counter */
|
||||
int ec[PC_NUM_HEIGHT_LAYER] = {0};
|
||||
/* Channel counters */
|
||||
int cc[PC_NUM_HEIGHT_LAYER] = {0};
|
||||
int fc[PC_NUM_HEIGHT_LAYER] = {0};
|
||||
int sc[PC_NUM_HEIGHT_LAYER] = {0};
|
||||
int bc[PC_NUM_HEIGHT_LAYER] = {0};
|
||||
int lc = 0;;
|
||||
|
||||
/* General MPEG (PCE) composition rules:
|
||||
- Over all:
|
||||
<normal height channels><top height channels><bottom height channels>
|
||||
- Within each height layer:
|
||||
<front channels><side channels><back channels>
|
||||
- Exception:
|
||||
The LFE channels have no height info and thus they are arranged at the very
|
||||
end of the normal height layer channels.
|
||||
*/
|
||||
|
||||
switch (elType)
|
||||
{
|
||||
@ -476,87 +649,206 @@ int CProgramConfig_LookupElement(
|
||||
case ID_SCE:
|
||||
/* search in front channels */
|
||||
for (i = 0; i < pPce->NumFrontChannelElements; i++) {
|
||||
int heightLayer = pPce->FrontElementHeightInfo[i];
|
||||
if (isCpe == pPce->FrontElementIsCpe[i] && pPce->FrontElementTagSelect[i] == tag) {
|
||||
chMapping[cc] = channelIdx;
|
||||
chType[cc] = ACT_FRONT;
|
||||
chIndex[cc] = fc;
|
||||
if (isCpe) {
|
||||
chMapping[cc+1] = channelIdx+1;
|
||||
chType[cc+1] = ACT_FRONT;
|
||||
chIndex[cc+1] = fc+1;
|
||||
int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
|
||||
AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_FRONT);
|
||||
for (h = heightLayer-1; h >= 0; h-=1) {
|
||||
int el;
|
||||
/* Count front channels/elements */
|
||||
for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
|
||||
if (pPce->FrontElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
/* Count side channels/elements */
|
||||
for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
|
||||
if (pPce->SideElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
/* Count back channels/elements */
|
||||
for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
|
||||
if (pPce->BackElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
if (h == 0) { /* normal height */
|
||||
elIdx += pPce->NumLfeChannelElements;
|
||||
chIdx += pPce->NumLfeChannelElements;
|
||||
}
|
||||
}
|
||||
*elMapping = ec;
|
||||
chMapping[chIdx] = channelIdx;
|
||||
chType[chIdx] = aChType;
|
||||
chIndex[chIdx] = fc[heightLayer];
|
||||
if (isCpe) {
|
||||
chMapping[chIdx+1] = channelIdx+1;
|
||||
chType[chIdx+1] = aChType;
|
||||
chIndex[chIdx+1] = fc[heightLayer]+1;
|
||||
}
|
||||
*elMapping = elIdx;
|
||||
return 1;
|
||||
}
|
||||
ec++;
|
||||
ec[heightLayer] += 1;
|
||||
if (pPce->FrontElementIsCpe[i]) {
|
||||
cc+=2; fc+=2;
|
||||
cc[heightLayer] += 2;
|
||||
fc[heightLayer] += 2;
|
||||
} else {
|
||||
cc++; fc++;
|
||||
cc[heightLayer] += 1;
|
||||
fc[heightLayer] += 1;
|
||||
}
|
||||
}
|
||||
/* search in side channels */
|
||||
for (i = 0; i < pPce->NumSideChannelElements; i++) {
|
||||
int heightLayer = pPce->SideElementHeightInfo[i];
|
||||
if (isCpe == pPce->SideElementIsCpe[i] && pPce->SideElementTagSelect[i] == tag) {
|
||||
chMapping[cc] = channelIdx;
|
||||
chType[cc] = ACT_SIDE;
|
||||
chIndex[cc] = sc;
|
||||
if (isCpe) {
|
||||
chMapping[cc+1] = channelIdx+1;
|
||||
chType[cc+1] = ACT_SIDE;
|
||||
chIndex[cc+1] = sc+1;
|
||||
int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
|
||||
AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_SIDE);
|
||||
for (h = heightLayer-1; h >= 0; h-=1) {
|
||||
int el;
|
||||
/* Count front channels/elements */
|
||||
for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
|
||||
if (pPce->FrontElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
/* Count side channels/elements */
|
||||
for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
|
||||
if (pPce->SideElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
/* Count back channels/elements */
|
||||
for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
|
||||
if (pPce->BackElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
if (h == 0) { /* LFE channels belong to the normal height layer */
|
||||
elIdx += pPce->NumLfeChannelElements;
|
||||
chIdx += pPce->NumLfeChannelElements;
|
||||
}
|
||||
}
|
||||
*elMapping = ec;
|
||||
chMapping[chIdx] = channelIdx;
|
||||
chType[chIdx] = aChType;
|
||||
chIndex[chIdx] = sc[heightLayer];
|
||||
if (isCpe) {
|
||||
chMapping[chIdx+1] = channelIdx+1;
|
||||
chType[chIdx+1] = aChType;
|
||||
chIndex[chIdx+1] = sc[heightLayer]+1;
|
||||
}
|
||||
*elMapping = elIdx;
|
||||
return 1;
|
||||
}
|
||||
ec++;
|
||||
ec[heightLayer] += 1;
|
||||
if (pPce->SideElementIsCpe[i]) {
|
||||
cc+=2; sc+=2;
|
||||
cc[heightLayer] += 2;
|
||||
sc[heightLayer] += 2;
|
||||
} else {
|
||||
cc++; sc++;
|
||||
cc[heightLayer] += 1;
|
||||
sc[heightLayer] += 1;
|
||||
}
|
||||
}
|
||||
/* search in back channels */
|
||||
for (i = 0; i < pPce->NumBackChannelElements; i++) {
|
||||
int heightLayer = pPce->BackElementHeightInfo[i];
|
||||
if (isCpe == pPce->BackElementIsCpe[i] && pPce->BackElementTagSelect[i] == tag) {
|
||||
chMapping[cc] = channelIdx;
|
||||
chType[cc] = ACT_BACK;
|
||||
chIndex[cc] = bc;
|
||||
if (isCpe) {
|
||||
chMapping[cc+1] = channelIdx+1;
|
||||
chType[cc+1] = ACT_BACK;
|
||||
chIndex[cc+1] = bc+1;
|
||||
int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
|
||||
AUDIO_CHANNEL_TYPE aChType = (AUDIO_CHANNEL_TYPE)((heightLayer<<4) | ACT_BACK);
|
||||
for (h = heightLayer-1; h >= 0; h-=1) {
|
||||
int el;
|
||||
/* Count front channels/elements */
|
||||
for (el = 0; el < pPce->NumFrontChannelElements; el+=1) {
|
||||
if (pPce->FrontElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
/* Count side channels/elements */
|
||||
for (el = 0; el < pPce->NumSideChannelElements; el+=1) {
|
||||
if (pPce->SideElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
/* Count back channels/elements */
|
||||
for (el = 0; el < pPce->NumBackChannelElements; el+=1) {
|
||||
if (pPce->BackElementHeightInfo[el] == h) {
|
||||
elIdx += 1;
|
||||
chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
if (h == 0) { /* normal height */
|
||||
elIdx += pPce->NumLfeChannelElements;
|
||||
chIdx += pPce->NumLfeChannelElements;
|
||||
}
|
||||
}
|
||||
*elMapping = ec;
|
||||
chMapping[chIdx] = channelIdx;
|
||||
chType[chIdx] = aChType;
|
||||
chIndex[chIdx] = bc[heightLayer];
|
||||
if (isCpe) {
|
||||
chMapping[chIdx+1] = channelIdx+1;
|
||||
chType[chIdx+1] = aChType;
|
||||
chIndex[chIdx+1] = bc[heightLayer]+1;
|
||||
}
|
||||
*elMapping = elIdx;
|
||||
return 1;
|
||||
}
|
||||
ec++;
|
||||
ec[heightLayer] += 1;
|
||||
if (pPce->BackElementIsCpe[i]) {
|
||||
cc+=2; bc+=2;
|
||||
cc[heightLayer] += 2;
|
||||
bc[heightLayer] += 2;
|
||||
} else {
|
||||
cc++; bc++;
|
||||
cc[heightLayer] += 1;
|
||||
bc[heightLayer] += 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_LFE:
|
||||
/* Initialize channel counter and element counter */
|
||||
cc = pPce->NumEffectiveChannels;
|
||||
ec = pPce->NumFrontChannelElements+ pPce->NumSideChannelElements + pPce->NumBackChannelElements;
|
||||
{ /* Unfortunately we have to go through all normal height
|
||||
layer elements to get the position of the LFE channels.
|
||||
Start with counting the front channels/elements at normal height */
|
||||
for (i = 0; i < pPce->NumFrontChannelElements; i+=1) {
|
||||
int heightLayer = pPce->FrontElementHeightInfo[i];
|
||||
ec[heightLayer] += 1;
|
||||
cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1;
|
||||
}
|
||||
/* Count side channels/elements at normal height */
|
||||
for (i = 0; i < pPce->NumSideChannelElements; i+=1) {
|
||||
int heightLayer = pPce->SideElementHeightInfo[i];
|
||||
ec[heightLayer] += 1;
|
||||
cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1;
|
||||
}
|
||||
/* Count back channels/elements at normal height */
|
||||
for (i = 0; i < pPce->NumBackChannelElements; i+=1) {
|
||||
int heightLayer = pPce->BackElementHeightInfo[i];
|
||||
ec[heightLayer] += 1;
|
||||
cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1;
|
||||
}
|
||||
|
||||
/* search in lfe channels */
|
||||
for (i = 0; i < pPce->NumLfeChannelElements; i++) {
|
||||
int elIdx = ec[0]; /* LFE channels belong to the normal height layer */
|
||||
int chIdx = cc[0];
|
||||
if ( pPce->LfeElementTagSelect[i] == tag ) {
|
||||
chMapping[cc] = channelIdx;
|
||||
*elMapping = ec;
|
||||
chType[cc] = ACT_LFE;
|
||||
chIndex[cc] = lc;
|
||||
chMapping[chIdx] = channelIdx;
|
||||
*elMapping = elIdx;
|
||||
chType[chIdx] = ACT_LFE;
|
||||
chIndex[chIdx] = lc;
|
||||
return 1;
|
||||
}
|
||||
ec++;
|
||||
cc++;
|
||||
lc++;
|
||||
ec[0] += 1;
|
||||
cc[0] += 1;
|
||||
lc += 1;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
/* Non audio elements */
|
||||
case ID_CCE:
|
||||
@ -590,13 +882,19 @@ int CProgramConfig_LookupElement(
|
||||
int CProgramConfig_GetElementTable(
|
||||
const CProgramConfig *pPce,
|
||||
MP4_ELEMENT_ID elList[],
|
||||
const INT elListSize
|
||||
const INT elListSize,
|
||||
UCHAR *pChMapIdx
|
||||
)
|
||||
{
|
||||
int i, el = 0;
|
||||
|
||||
if ( elListSize
|
||||
< pPce->NumFrontChannelElements + pPce->NumSideChannelElements + pPce->NumBackChannelElements + pPce->NumLfeChannelElements
|
||||
FDK_ASSERT(elList != NULL);
|
||||
FDK_ASSERT(pChMapIdx != NULL);
|
||||
|
||||
*pChMapIdx = 0;
|
||||
|
||||
if ( elListSize
|
||||
< pPce->NumFrontChannelElements + pPce->NumSideChannelElements + pPce->NumBackChannelElements + pPce->NumLfeChannelElements
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
@ -623,6 +921,47 @@ int CProgramConfig_GetElementTable(
|
||||
}
|
||||
|
||||
|
||||
/* Find an corresponding channel configuration if possible */
|
||||
switch (pPce->NumChannels) {
|
||||
case 1: case 2: case 3: case 4: case 5: case 6:
|
||||
/* One and two channels have no alternatives. The other ones are mapped directly to the
|
||||
corresponding channel config. Because of legacy reasons or for lack of alternative mappings. */
|
||||
*pChMapIdx = pPce->NumChannels;
|
||||
break;
|
||||
case 7:
|
||||
{
|
||||
C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
|
||||
/* Create a PCE for the config to test ... */
|
||||
CProgramConfig_GetDefault(tmpPce, 11);
|
||||
/* ... and compare it with the given one. */
|
||||
*pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce)&0xE)) ? 11 : 0;
|
||||
/* If compare result is 0 or 1 we can be sure that it is channel config 11. */
|
||||
C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
{ /* Try the four possible 7.1ch configurations. One after the other. */
|
||||
UCHAR testCfg[4] = { 32, 14, 12, 7};
|
||||
C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
|
||||
for (i=0; i<4; i+=1) {
|
||||
/* Create a PCE for the config to test ... */
|
||||
CProgramConfig_GetDefault(tmpPce, testCfg[i]);
|
||||
/* ... and compare it with the given one. */
|
||||
if (!(CProgramConfig_Compare(pPce, tmpPce)&0xE)) {
|
||||
/* If the compare result is 0 or 1 than the two channel configurations match. */
|
||||
/* Explicit mapping of 7.1 side channel configuration to 7.1 rear channel mapping. */
|
||||
*pChMapIdx = (testCfg[i]==32) ? 12 : testCfg[i];
|
||||
}
|
||||
}
|
||||
C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* The PCE does not match any predefined channel configuration. */
|
||||
*pChMapIdx = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return el;
|
||||
}
|
||||
#endif
|
||||
@ -714,7 +1053,7 @@ TRANSPORTDEC_ERROR GaSpecificConfig_Parse( CSGaSpecificConfig *self,
|
||||
#ifdef TP_ELD_ENABLE
|
||||
|
||||
static INT ld_sbr_header( const CSAudioSpecificConfig *asc,
|
||||
HANDLE_FDK_BITSTREAM hBs,
|
||||
HANDLE_FDK_BITSTREAM hBs,
|
||||
CSTpCallBacks *cb )
|
||||
{
|
||||
const int channelConfiguration = asc->m_channelConfiguration;
|
||||
@ -728,6 +1067,8 @@ static INT ld_sbr_header( const CSAudioSpecificConfig *asc,
|
||||
}
|
||||
|
||||
switch ( channelConfiguration ) {
|
||||
case 14:
|
||||
case 12:
|
||||
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:
|
||||
@ -737,6 +1078,8 @@ static INT ld_sbr_header( const CSAudioSpecificConfig *asc,
|
||||
error |= cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, asc->m_extensionSamplingFrequency, asc->m_samplesPerFrame, AOT_ER_AAC_ELD, ID_CPE, i++);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
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++);
|
||||
@ -802,24 +1145,6 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
|
||||
}
|
||||
|
||||
switch (eldExtType) {
|
||||
case ELDEXT_LDSAC:
|
||||
esc->m_useLdQmfTimeAlign = 1;
|
||||
if (cb->cbSsc != NULL) {
|
||||
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
|
||||
cb->cbSscData,
|
||||
hBs,
|
||||
asc->m_aot,
|
||||
asc->m_samplingFrequency,
|
||||
1, /* muxMode */
|
||||
len
|
||||
);
|
||||
} else {
|
||||
ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT;
|
||||
}
|
||||
if (ErrorStatus != TRANSPORTDEC_OK) {
|
||||
goto bail;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for(cnt=0; cnt<len; cnt++) {
|
||||
FDKreadBits(hBs, 8 );
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* library info */
|
||||
#define TP_LIB_VL0 2
|
||||
#define TP_LIB_VL1 3
|
||||
#define TP_LIB_VL2 3
|
||||
#define TP_LIB_VL2 4
|
||||
#define TP_LIB_TITLE "MPEG Transport"
|
||||
#define TP_LIB_BUILD_DATE __DATE__
|
||||
#define TP_LIB_BUILD_TIME __TIME__
|
||||
|
@ -146,12 +146,15 @@ typedef struct
|
||||
|
||||
UCHAR FrontElementIsCpe[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR FrontElementTagSelect[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR FrontElementHeightInfo[PC_FSB_CHANNELS_MAX];
|
||||
|
||||
UCHAR SideElementIsCpe[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR SideElementTagSelect[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR SideElementHeightInfo[PC_FSB_CHANNELS_MAX];
|
||||
|
||||
UCHAR BackElementIsCpe[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR BackElementTagSelect[PC_FSB_CHANNELS_MAX];
|
||||
UCHAR BackElementHeightInfo[PC_FSB_CHANNELS_MAX];
|
||||
|
||||
UCHAR LfeElementTagSelect[PC_LFE_CHANNELS_MAX];
|
||||
|
||||
@ -324,16 +327,23 @@ int getSamplingRateIndex( UINT samplingRate )
|
||||
*/
|
||||
static inline int getNumberOfTotalChannels(int channelConfig)
|
||||
{
|
||||
if (channelConfig > 0 && channelConfig < 8)
|
||||
return (channelConfig == 7)?8:channelConfig;
|
||||
else
|
||||
switch (channelConfig) {
|
||||
case 1: case 2: case 3:
|
||||
case 4: case 5: case 6:
|
||||
return channelConfig;
|
||||
case 7: case 12: case 14:
|
||||
return 8;
|
||||
case 11:
|
||||
return 7;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
int getNumberOfEffectiveChannels(const int channelConfig)
|
||||
{
|
||||
const int n[] = {0,1,2,3,4,5,5,7};
|
||||
{ /* index: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 */
|
||||
const int n[] = {0,1,2,3,4,5,5,7,0,0, 0, 6, 7, 0, 7, 0};
|
||||
return n[channelConfig];
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
/* library info */
|
||||
#define TP_LIB_VL0 2
|
||||
#define TP_LIB_VL1 3
|
||||
#define TP_LIB_VL2 3
|
||||
#define TP_LIB_VL2 4
|
||||
#define TP_LIB_TITLE "MPEG Transport"
|
||||
#define TP_LIB_BUILD_DATE __DATE__
|
||||
#define TP_LIB_BUILD_TIME __TIME__
|
||||
|
@ -95,69 +95,88 @@ amm-info@iis.fraunhofer.de
|
||||
#include "machine_type.h"
|
||||
#include "common_fix.h"
|
||||
#include "FDK_audio.h"
|
||||
#include "FDK_bitstream.h"
|
||||
|
||||
/* ------------------------ *
|
||||
* MODULE SETTINGS: *
|
||||
* ------------------------ */
|
||||
/* #define PCM_UPMIX_ENABLE */ /*!< Generally enable up mixing. */
|
||||
#define PCM_DOWNMIX_ENABLE /*!< Generally enable down mixing. */
|
||||
#define DVB_MIXDOWN_ENABLE /*!< Enable this to support DVB ancillary data for encoder
|
||||
assisted downmixing of MPEG-4 AAC and
|
||||
MPEG-1/2 layer 2 streams. PCM_DOWNMIX_ENABLE has to
|
||||
be enabled, too! */
|
||||
#define MPEG_PCE_MIXDOWN_ENABLE /*!< Enable this to support MPEG matrix mixdown with a
|
||||
coefficient carried in the PCE. PCM_DOWNMIX_ENABLE
|
||||
has to be enabled, too! */
|
||||
/* #define ARIB_MIXDOWN_ENABLE */ /*!< Enable modifications to the MPEG PCE mixdown method
|
||||
to fulfill ARIB standard. MPEG_PCE_MIXDOWN_ENABLE has
|
||||
to be set. */
|
||||
|
||||
/* ------------------------ *
|
||||
* ERROR CODES: *
|
||||
* ------------------------ */
|
||||
typedef enum
|
||||
{
|
||||
PCMDMX_OK = 0x0, /*!< No error happened. */
|
||||
PCMDMX_OUT_OF_MEMORY = 0x2, /*!< Not enough memory to set up an instance of the module. */
|
||||
PCMDMX_UNKNOWN = 0x5, /*!< Error condition is of unknown reason, or from a third
|
||||
party module. */
|
||||
PCMDMX_INVALID_HANDLE, /*!< The given instance handle is not valid. */
|
||||
PCMDMX_INVALID_ARGUMENT, /*!< One of the parameters handed over is invalid. */
|
||||
PCMDMX_INVALID_CH_CONFIG, /*!< The given channel configuration is not supported and
|
||||
thus no processing was performed. */
|
||||
PCMDMX_INVALID_MODE, /*!< The set configuration/mode is not applicable. */
|
||||
PCMDMX_UNKNOWN_PARAM, /*!< The handed parameter is not known/supported. */
|
||||
PCMDMX_UNABLE_TO_SET_PARAM, /*!< Unable to set the specific parameter. Most probably
|
||||
the value ist out of range. */
|
||||
PCMDMX_CORRUPT_ANC_DATA /*!< The read ancillary data was corrupt. */
|
||||
PCMDMX_OK = 0x0, /*!< No error happened. */
|
||||
|
||||
pcm_dmx_fatal_error_start,
|
||||
PCMDMX_OUT_OF_MEMORY = 0x2, /*!< Not enough memory to set up an instance of the module. */
|
||||
PCMDMX_UNKNOWN = 0x5, /*!< Error condition is of unknown reason, or from a third
|
||||
party module. */
|
||||
pcm_dmx_fatal_error_end,
|
||||
|
||||
PCMDMX_INVALID_HANDLE, /*!< The given instance handle is not valid. */
|
||||
PCMDMX_INVALID_ARGUMENT, /*!< One of the parameters handed over is invalid. */
|
||||
PCMDMX_INVALID_CH_CONFIG, /*!< The given channel configuration is not supported and thus
|
||||
no processing was performed. */
|
||||
PCMDMX_INVALID_MODE, /*!< The set configuration/mode is not applicable. */
|
||||
PCMDMX_UNKNOWN_PARAM, /*!< The handed parameter is not known/supported. */
|
||||
PCMDMX_UNABLE_TO_SET_PARAM, /*!< Unable to set the specific parameter. Most probably the
|
||||
value ist out of range. */
|
||||
PCMDMX_CORRUPT_ANC_DATA /*!< The read ancillary data was corrupt. */
|
||||
|
||||
} PCMDMX_ERROR;
|
||||
|
||||
/** Macro to identify fatal errors. */
|
||||
#define PCMDMX_IS_FATAL_ERROR(err) ( (((err)>=pcm_dmx_fatal_error_start) && ((err)<=pcm_dmx_fatal_error_end)) ? 1 : 0)
|
||||
|
||||
/* ------------------------ *
|
||||
* RUNTIME PARAMS: *
|
||||
* ------------------------ */
|
||||
typedef enum
|
||||
{
|
||||
DMX_BS_DATA_EXPIRY_FRAME, /*!< The number of frames without new metadata that have to
|
||||
go by before the bitstream data expires. The value 0
|
||||
disables expiry. */
|
||||
DMX_BS_DATA_DELAY, /*!< The number of delay frames of the output samples
|
||||
compared to the bitstream data. */
|
||||
NUMBER_OF_OUTPUT_CHANNELS , /*!< The number of output channels (equals the number of
|
||||
channels processed by the audio output setup). */
|
||||
DUAL_CHANNEL_DOWNMIX_MODE /*!< Downmix mode for two channel audio data. */
|
||||
|
||||
DMX_BS_DATA_EXPIRY_FRAME, /*!< The number of frames without new metadata that have to go
|
||||
by before the bitstream data expires. The value 0 disables
|
||||
expiry. */
|
||||
DMX_BS_DATA_DELAY, /*!< The number of delay frames of the output samples compared
|
||||
to the bitstream data. */
|
||||
MIN_NUMBER_OF_OUTPUT_CHANNELS, /*!< The minimum number of output channels. For all input
|
||||
configurations that have less than the given channels the
|
||||
module will modify the output automatically to obtain the
|
||||
given number of output channels. Mono signals will be
|
||||
duplicated. If more than two output channels are desired
|
||||
the module just adds empty channels. The parameter value
|
||||
must be either -1, 0, 1, 2, 6 or 8. If the value is
|
||||
greater than zero and exceeds the value of parameter
|
||||
MAX_NUMBER_OF_OUTPUT_CHANNELS the latter will be set to
|
||||
the same value. Both values -1 and 0 disable the feature. */
|
||||
MAX_NUMBER_OF_OUTPUT_CHANNELS, /*!< The maximum number of output channels. For all input
|
||||
configurations that have more than the given channels the
|
||||
module will apply a mixdown automatically to obtain the
|
||||
given number of output channels. The value must be either
|
||||
-1, 0, 1, 2, 6 or 8. If it is greater than zero and lower
|
||||
or equal than the value of MIN_NUMBER_OF_OUTPUT_CHANNELS
|
||||
parameter the latter will be set to the same value.
|
||||
The values -1 and 0 disable the feature. */
|
||||
DMX_DUAL_CHANNEL_MODE, /*!< Downmix mode for two channel audio data. */
|
||||
DMX_PSEUDO_SURROUND_MODE /*!< Defines how module handles pseudo surround compatible
|
||||
signals. See PSEUDO_SURROUND_MODE type for details. */
|
||||
} PCMDMX_PARAM;
|
||||
|
||||
/* Parameter value types */
|
||||
typedef enum
|
||||
{
|
||||
NEVER_DO_PS_DMX = -1, /*!< Never create a pseudo surround compatible downmix. */
|
||||
AUTO_PS_DMX = 0, /*!< Create a pseudo surround compatible downmix only if
|
||||
signalled in bitstreams meta data. (Default) */
|
||||
FORCE_PS_DMX = 1 /*!< Always create a pseudo surround compatible downmix.
|
||||
CAUTION: This can lead to excessive signal cancellations
|
||||
and signal level differences for non-compatible signals. */
|
||||
} PSEUDO_SURROUND_MODE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STEREO_MODE = 0x0, /*!< Leave stereo signals as they are. */
|
||||
CH1_MODE = 0x1, /*!< Create a dual mono output signal from channel 1. */
|
||||
CH2_MODE = 0x2, /*!< Create a dual mono output signal from channel 2. */
|
||||
MIXED_MODE = 0x3 /*!< Create a dual mono output signal by mixing the two channels. */
|
||||
|
||||
STEREO_MODE = 0x0, /*!< Leave stereo signals as they are. */
|
||||
CH1_MODE = 0x1, /*!< Create a dual mono output signal from channel 1. */
|
||||
CH2_MODE = 0x2, /*!< Create a dual mono output signal from channel 2. */
|
||||
MIXED_MODE = 0x3 /*!< Create a dual mono output signal by mixing the two
|
||||
channels. */
|
||||
} DUAL_CHANNEL_MODE;
|
||||
|
||||
|
||||
@ -178,7 +197,7 @@ extern "C"
|
||||
|
||||
/** Open and initialize an instance of the PCM downmix module
|
||||
* @param [out] Pointer to a buffer receiving the handle of the new instance.
|
||||
* @returns Returns an error code.
|
||||
* @returns Returns an error code.
|
||||
**/
|
||||
PCMDMX_ERROR pcmDmx_Open (
|
||||
HANDLE_PCM_DOWNMIX *pSelf
|
||||
@ -188,20 +207,46 @@ PCMDMX_ERROR pcmDmx_Open (
|
||||
* @param [in] Handle of PCM downmix instance.
|
||||
* @param [in] Parameter to be set.
|
||||
* @param [in] Parameter value.
|
||||
* @returns Returns an error code.
|
||||
* @returns Returns an error code.
|
||||
**/
|
||||
PCMDMX_ERROR pcmDmx_SetParam (
|
||||
HANDLE_PCM_DOWNMIX self,
|
||||
PCMDMX_PARAM param,
|
||||
UINT value
|
||||
const PCMDMX_PARAM param,
|
||||
const INT value
|
||||
);
|
||||
|
||||
/** Read the ancillary data transported in DSEs of DVB streams with MPEG-4 content
|
||||
/** Get one parameter value of one PCM downmix module instance.
|
||||
* @param [in] Handle of PCM downmix module instance.
|
||||
* @param [in] Parameter to be set.
|
||||
* @param [out] Pointer to buffer receiving the parameter value.
|
||||
* @returns Returns an error code.
|
||||
**/
|
||||
PCMDMX_ERROR pcmDmx_GetParam (
|
||||
HANDLE_PCM_DOWNMIX self,
|
||||
const PCMDMX_PARAM param,
|
||||
INT * const pValue
|
||||
);
|
||||
|
||||
/** Read downmix meta-data directly from a given bitstream.
|
||||
* @param [in] Handle of PCM downmix instance.
|
||||
* @param [in] Handle of FDK bitstream buffer.
|
||||
* @param [in] Length of ancillary data in bits.
|
||||
* @param [in] Flag indicating wheter the ancillary data is from a MPEG-1/2 or an MPEG-4 stream.
|
||||
* @returns Returns an error code.
|
||||
**/
|
||||
PCMDMX_ERROR pcmDmx_Parse (
|
||||
HANDLE_PCM_DOWNMIX self,
|
||||
HANDLE_FDK_BITSTREAM hBitStream,
|
||||
UINT ancDataBits,
|
||||
int isMpeg2
|
||||
);
|
||||
|
||||
/** Read downmix meta-data from a given data buffer.
|
||||
* @param [in] Handle of PCM downmix instance.
|
||||
* @param [in] Pointer to ancillary data buffer.
|
||||
* @param [in] Size of ancillary data.
|
||||
* @param [in] Size of ancillary data in bytes.
|
||||
* @param [in] Flag indicating wheter the ancillary data is from a MPEG-1/2 or an MPEG-4 stream.
|
||||
* @returns Returns an error code.
|
||||
* @returns Returns an error code.
|
||||
**/
|
||||
PCMDMX_ERROR pcmDmx_ReadDvbAncData (
|
||||
HANDLE_PCM_DOWNMIX self,
|
||||
@ -211,12 +256,11 @@ PCMDMX_ERROR pcmDmx_ReadDvbAncData (
|
||||
);
|
||||
|
||||
/** Set the matrix mixdown information extracted from the PCE of an AAC bitstream.
|
||||
* Note: Call only if matrix_mixdown_idx_present is true.
|
||||
* @param [in] Handle of PCM downmix instance.
|
||||
* @param [in] Matrix mixdown index present flag extracted from PCE.
|
||||
* @param [in] The 2 bit matrix mixdown index extracted from PCE.
|
||||
* @param [in] The pseudo surround enable flag extracted from PCE.
|
||||
* @returns Returns an error code.
|
||||
* @returns Returns an error code.
|
||||
**/
|
||||
PCMDMX_ERROR pcmDmx_SetMatrixMixdownFromPce (
|
||||
HANDLE_PCM_DOWNMIX self,
|
||||
@ -235,34 +279,42 @@ PCMDMX_ERROR pcmDmx_Reset (
|
||||
UINT flags
|
||||
);
|
||||
|
||||
/** Apply down or up mixing.
|
||||
/** Create a mixdown, bypass or extend the output signal depending on the modules settings and the
|
||||
* respective given input configuration.
|
||||
*
|
||||
* \param [in] Handle of PCM downmix module instance.
|
||||
* \param [inout] Pointer to time buffer with decoded PCM samples.
|
||||
* \param [in] Pointer where the amount of output samples is returned into.
|
||||
* \param [inout] Pointer where the amount of output channels is returned into.
|
||||
* \param [in] Flag which indicates if output time data are writtern interleaved or as subsequent blocks.
|
||||
* \param [inout] Array were the corresponding channel type for each output audio channel is stored into.
|
||||
* \param [inout] Array were the corresponding channel type index for each output audio channel is stored into.
|
||||
* \param [in] Array containing the output channel mapping to be used (From MPEG PCE ordering to whatever is required).
|
||||
*
|
||||
* @returns Returns an error code.
|
||||
* \param [in] The I/O block size which is the number of samples per channel.
|
||||
* \param [inout] Pointer to buffer that holds the number of input channels and where the
|
||||
* amount of output channels is written to.
|
||||
* \param [in] Flag which indicates if output time data is writtern interleaved or as
|
||||
* subsequent blocks.
|
||||
* \param [inout] Array were the corresponding channel type for each output audio channel is
|
||||
* stored into.
|
||||
* \param [inout] Array were the corresponding channel type index for each output audio channel
|
||||
* is stored into.
|
||||
* \param [in] Array containing the output channel mapping to be used (from MPEG PCE ordering
|
||||
* to whatever is required).
|
||||
* \param [out] Pointer on a field receiving the scale factor that has to be applied on all
|
||||
* samples afterwards. If the handed pointer is NULL the final scaling is done
|
||||
* internally.
|
||||
* @returns Returns an error code.
|
||||
**/
|
||||
PCMDMX_ERROR pcmDmx_ApplyFrame (
|
||||
HANDLE_PCM_DOWNMIX self,
|
||||
INT_PCM *pPcmBuf,
|
||||
UINT frameSize,
|
||||
INT *nChannels,
|
||||
|
||||
int fInterleaved,
|
||||
AUDIO_CHANNEL_TYPE channelType[],
|
||||
UCHAR channelIndices[],
|
||||
const UCHAR channelMapping[][8]
|
||||
const UCHAR channelMapping[][8],
|
||||
INT *pDmxOutScale
|
||||
);
|
||||
|
||||
/** Close an instance of the PCM downmix module.
|
||||
* @param [inout] Pointer to a buffer containing the handle of the instance.
|
||||
* @returns Returns an error code.
|
||||
* @returns Returns an error code.
|
||||
**/
|
||||
PCMDMX_ERROR pcmDmx_Close (
|
||||
HANDLE_PCM_DOWNMIX *pSelf
|
||||
@ -270,7 +322,7 @@ PCMDMX_ERROR pcmDmx_Close (
|
||||
|
||||
/** Get library info for this module.
|
||||
* @param [out] Pointer to an allocated LIB_INFO structure.
|
||||
* @returns Returns an error code.
|
||||
* @returns Returns an error code.
|
||||
*/
|
||||
PCMDMX_ERROR pcmDmx_GetLibInfo( LIB_INFO *info );
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -308,7 +308,7 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
|
||||
INT_PCM *timeData,
|
||||
int *numChannels,
|
||||
int *sampleRate,
|
||||
const UCHAR channelMapping[(6)],
|
||||
const UCHAR channelMapping[(8)],
|
||||
const int interleaved,
|
||||
const int coreDecodedOk,
|
||||
UCHAR *psDecoded );
|
||||
|
@ -107,19 +107,19 @@ amm-info@iis.fraunhofer.de
|
||||
/*! SBR Decoder main structure */
|
||||
C_ALLOC_MEM(Ram_SbrDecoder, struct SBR_DECODER_INSTANCE, 1)
|
||||
/*! SBR Decoder element data <br>
|
||||
Dimension: (4) */
|
||||
C_ALLOC_MEM2(Ram_SbrDecElement, SBR_DECODER_ELEMENT, 1, (4))
|
||||
Dimension: (8) */
|
||||
C_ALLOC_MEM2(Ram_SbrDecElement, SBR_DECODER_ELEMENT, 1, (8))
|
||||
/*! SBR Decoder individual channel data <br>
|
||||
Dimension: (6) */
|
||||
C_ALLOC_MEM2(Ram_SbrDecChannel, SBR_CHANNEL, 1, (6)+1)
|
||||
Dimension: (8) */
|
||||
C_ALLOC_MEM2(Ram_SbrDecChannel, SBR_CHANNEL, 1, (8)+1)
|
||||
|
||||
/*! Filter states for QMF-synthesis. <br>
|
||||
Dimension: #(6) * (#QMF_FILTER_STATE_SYN_SIZE-#(64)) */
|
||||
C_AALLOC_MEM2_L(Ram_sbr_QmfStatesSynthesis, FIXP_QSS, (640)-(64), (6)+1, SECT_DATA_L1)
|
||||
Dimension: #(8) * (#QMF_FILTER_STATE_SYN_SIZE-#(64)) */
|
||||
C_AALLOC_MEM2_L(Ram_sbr_QmfStatesSynthesis, FIXP_QSS, (640)-(64), (8)+1, SECT_DATA_L1)
|
||||
|
||||
/*! Delayed spectral data needed for the dynamic framing of SBR.
|
||||
For mp3PRO, 1/3 of a frame is buffered (#(6) 6) */
|
||||
C_AALLOC_MEM2(Ram_sbr_OverlapBuffer, FIXP_DBL, 2 * (6) * (64), (6)+1)
|
||||
C_AALLOC_MEM2(Ram_sbr_OverlapBuffer, FIXP_DBL, 2 * (6) * (64), (8)+1)
|
||||
|
||||
/*! Static Data of PS */
|
||||
|
||||
|
@ -118,8 +118,8 @@ typedef struct
|
||||
|
||||
struct SBR_DECODER_INSTANCE
|
||||
{
|
||||
SBR_DECODER_ELEMENT *pSbrElement[(4)];
|
||||
SBR_HEADER_DATA sbrHeader[(4)][(1)+1]; /* Sbr header for each individual channel of an element */
|
||||
SBR_DECODER_ELEMENT *pSbrElement[(8)];
|
||||
SBR_HEADER_DATA sbrHeader[(8)][(1)+1]; /* Sbr header for each individual channel of an element */
|
||||
|
||||
FIXP_DBL *workBuffer1;
|
||||
FIXP_DBL *workBuffer2;
|
||||
|
@ -95,7 +95,7 @@ amm-info@iis.fraunhofer.de
|
||||
|
||||
|
||||
|
||||
#define SBRDEC_MAX_DRC_CHANNELS (6)
|
||||
#define SBRDEC_MAX_DRC_CHANNELS (8)
|
||||
#define SBRDEC_MAX_DRC_BANDS ( 16 )
|
||||
|
||||
typedef struct
|
||||
|
@ -137,7 +137,7 @@ amm-info@iis.fraunhofer.de
|
||||
/* Decoder library info */
|
||||
#define SBRDECODER_LIB_VL0 2
|
||||
#define SBRDECODER_LIB_VL1 2
|
||||
#define SBRDECODER_LIB_VL2 3
|
||||
#define SBRDECODER_LIB_VL2 4
|
||||
#define SBRDECODER_LIB_TITLE "SBR Decoder"
|
||||
#define SBRDECODER_LIB_BUILD_DATE __DATE__
|
||||
#define SBRDECODER_LIB_BUILD_TIME __TIME__
|
||||
@ -428,7 +428,7 @@ SBR_ERROR sbrDecoder_InitElement (
|
||||
int nSbrElementsStart = self->numSbrElements;
|
||||
|
||||
/* Check core codec AOT */
|
||||
if (! sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (4)) {
|
||||
if (! sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (8)) {
|
||||
sbrError = SBRDEC_UNSUPPORTED_CONFIG;
|
||||
goto bail;
|
||||
}
|
||||
@ -615,7 +615,7 @@ INT sbrDecoder_Header (
|
||||
SBR_ERROR sbrError = SBRDEC_OK;
|
||||
int headerIndex;
|
||||
|
||||
if ( self == NULL || elementIndex > (4) )
|
||||
if ( self == NULL || elementIndex > (8) )
|
||||
{
|
||||
return SBRDEC_UNSUPPORTED_CONFIG;
|
||||
}
|
||||
@ -767,7 +767,7 @@ SBRDEC_DRC_CHANNEL * sbrDecoder_drcGetChannel( const HANDLE_SBRDECODER self, con
|
||||
SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
|
||||
int elementIndex, elChanIdx=0, numCh=0;
|
||||
|
||||
for (elementIndex = 0; (elementIndex < (4)) && (numCh <= channel); elementIndex++)
|
||||
for (elementIndex = 0; (elementIndex < (8)) && (numCh <= channel); elementIndex++)
|
||||
{
|
||||
SBR_DECODER_ELEMENT *pSbrElement = self->pSbrElement[elementIndex];
|
||||
int c, elChannels;
|
||||
@ -829,7 +829,7 @@ SBR_ERROR sbrDecoder_drcFeedChannel ( HANDLE_SBRDECODER self,
|
||||
if (self == NULL) {
|
||||
return SBRDEC_NOT_INITIALIZED;
|
||||
}
|
||||
if (ch > (6) || pNextFact_mag == NULL) {
|
||||
if (ch > (8) || pNextFact_mag == NULL) {
|
||||
return SBRDEC_SET_PARAM_FAIL;
|
||||
}
|
||||
|
||||
@ -874,7 +874,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self,
|
||||
SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
|
||||
|
||||
if ( (self == NULL)
|
||||
|| (ch > (6))
|
||||
|| (ch > (8))
|
||||
|| (self->numSbrElements == 0)
|
||||
|| (self->numSbrChannels == 0) ) {
|
||||
return;
|
||||
@ -1375,7 +1375,7 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
|
||||
INT_PCM *timeData,
|
||||
int *numChannels,
|
||||
int *sampleRate,
|
||||
const UCHAR channelMapping[(6)],
|
||||
const UCHAR channelMapping[(8)],
|
||||
const int interleaved,
|
||||
const int coreDecodedOk,
|
||||
UCHAR *psDecoded )
|
||||
@ -1496,7 +1496,7 @@ SBR_ERROR sbrDecoder_Close ( HANDLE_SBRDECODER *pSelf )
|
||||
FreeRam_SbrDecWorkBuffer2(&self->workBuffer2);
|
||||
}
|
||||
|
||||
for (i = 0; i < (4); i++) {
|
||||
for (i = 0; i < (8); i++) {
|
||||
sbrDecoder_DestroyElement( self, i );
|
||||
}
|
||||
|
||||
|
@ -263,17 +263,29 @@ typedef enum {
|
||||
|
||||
} CHANNEL_MODE;
|
||||
|
||||
/** Speaker description tags */
|
||||
/**
|
||||
* Speaker description tags.
|
||||
* Do not change the enumeration values unless it keeps the following segmentation:
|
||||
* - Bit 0-3: Horizontal postion (0: none, 1: front, 2: side, 3: back, 4: lfe)
|
||||
* - Bit 4-7: Vertical position (0: normal, 1: top, 2: bottom)
|
||||
*/
|
||||
typedef enum {
|
||||
ACT_NONE,
|
||||
ACT_FRONT,
|
||||
ACT_SIDE,
|
||||
ACT_BACK,
|
||||
ACT_LFE,
|
||||
ACT_FRONT_TOP,
|
||||
ACT_SIDE_TOP,
|
||||
ACT_BACK_TOP,
|
||||
ACT_TOP /* Ts */
|
||||
ACT_NONE = 0x00,
|
||||
ACT_FRONT = 0x01, /*!< Front speaker position (at normal height) */
|
||||
ACT_SIDE = 0x02, /*!< Side speaker position (at normal height) */
|
||||
ACT_BACK = 0x03, /*!< Back speaker position (at normal height) */
|
||||
ACT_LFE = 0x04, /*!< Low frequency effect speaker postion (front) */
|
||||
|
||||
ACT_TOP = 0x10, /*!< Top speaker area (for combination with speaker positions) */
|
||||
ACT_FRONT_TOP = 0x11, /*!< Top front speaker = (ACT_FRONT|ACT_TOP) */
|
||||
ACT_SIDE_TOP = 0x12, /*!< Top side speaker = (ACT_SIDE |ACT_TOP) */
|
||||
ACT_BACK_TOP = 0x13, /*!< Top back speaker = (ACT_BACK |ACT_TOP) */
|
||||
|
||||
ACT_BOTTOM = 0x20, /*!< Bottom speaker area (for combination with speaker positions) */
|
||||
ACT_FRONT_BOTTOM = 0x21, /*!< Bottom front speaker = (ACT_FRONT|ACT_BOTTOM) */
|
||||
ACT_SIDE_BOTTOM = 0x22, /*!< Bottom side speaker = (ACT_SIDE |ACT_BOTTOM) */
|
||||
ACT_BACK_BOTTOM = 0x23 /*!< Bottom back speaker = (ACT_BACK |ACT_BOTTOM) */
|
||||
|
||||
} AUDIO_CHANNEL_TYPE;
|
||||
|
||||
typedef enum
|
||||
|
@ -99,7 +99,7 @@ amm-info@iis.fraunhofer.de
|
||||
/* library info */
|
||||
#define SYS_LIB_VL0 1
|
||||
#define SYS_LIB_VL1 3
|
||||
#define SYS_LIB_VL2 4
|
||||
#define SYS_LIB_VL2 5
|
||||
#define SYS_LIB_TITLE "System Integration Library"
|
||||
#define SYS_LIB_BUILD_DATE __DATE__
|
||||
#define SYS_LIB_BUILD_TIME __TIME__
|
||||
|
Loading…
Reference in New Issue
Block a user