aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2016-04-08 12:05:12 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2016-04-08 19:10:30 +0000
commit203e3f28fbebec7011342017fafc2a0bda0ce530 (patch)
tree359ed01256a717b0161bfba21783634f1250471a
parent46ba3676b854acbc69a4c7845f578d4c2886377b (diff)
downloadfdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.tar.gz
fdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.tar.bz2
fdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.zip
AAC/SBR decoder improvements and bugfixes
* AAC-Decoder - Add support for AOT 20 (ER-AAC scalable) (base layer only) - Add support for AAC as used in Digital Radio Mondiale (DRM30/DRM+) Modified file(s): libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp libFDK/src/FDK_core.cpp libFDK/src/FDK_tools_rom.cpp libMpegTPDec/src/tpdec_asc.cpp libMpegTPDec/src/tpdec_lib.cpp libMpegTPDec/src/version libSBRdec/include/sbrdecoder.h libSBRdec/src/env_extr.h libSBRdec/src/sbrdecoder.cpp Added file(s): libMpegTPDec/src/tpdec_drm.cpp libMpegTPDec/src/tpdec_drm.h - Fix sanity check in HCR module that was performed at the wrong point in time. Modified file(s): libAACdec/src/aacdecoder_lib.cpp libAACdec/src/block.cpp - Extend core sampling rate support up to 96 kHz. Modified file(s): libAACdec/src/aac_rom.cpp libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp - Return correct audio output channel description according number of output channels. Modified file(s): libAACdec/src/aacdecoder_lib.cpp - Indroduce decoder intern output buffer. This change allows to use framework output buffer with the actual size of the deocder output channels. Modified file(s): libAACdec/include/aacdecoder_lib.h libAACdec/src/aacdecoder.h libAACdec/src/aacdecoder_lib.cpp * SBR-Decoder - Increase robustness for erroneous input data. - Improve error concealment performance. - Fix handling of lowest sub-band for LD-SBR Modified file(s): libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp libSBRdec/src/env_calc.cpp libSBRdec/src/env_dec.cpp libSBRdec/src/env_extr.cpp libSBRdec/src/env_extr.h libSBRdec/src/sbr_dec.cpp libSBRdec/src/sbr_rom.cpp libSBRdec/src/sbr_rom.h libSBRdec/src/sbrdecoder.cpp - Add QMF delay compensation for ELD v2 streams decoded with the complex low delay filter-bank. Modified file(s): libSBRdec/src/sbr_dec.cpp libSBRdec/src/sbr_dec.h libSBRdec/src/sbrdecoder.cpp - Introduce a different handling of frames to be flushed dependent on whether there are delayed frames available or not. Modified file(s): libSBRdec/src/sbr_ram.h libSBRdec/src/sbrdecoder.cpp - Calculate the correct number of samples for dual-mono copy in case of no available PS data. Modified file(s): libSBRdec/src/sbrdecoder.cpp * SYS-Library - Change include order of genericStds.h to prevent conflict with definitions which are also used in math.h. Modified file(s): libSYS/src/genericStds.cpp Change-Id: I3ecffbad85f39b056213107955cfadbeb3f4b6e1
-rw-r--r--documentation/aacDecoder.pdfbin505567 -> 387906 bytes
-rw-r--r--libAACdec/include/aacdecoder_lib.h3
-rw-r--r--libAACdec/src/aac_rom.cpp85
-rw-r--r--libAACdec/src/aacdecoder.cpp37
-rw-r--r--libAACdec/src/aacdecoder.h4
-rw-r--r--libAACdec/src/aacdecoder_lib.cpp43
-rw-r--r--libAACdec/src/block.cpp6
-rw-r--r--libFDK/src/FDK_core.cpp2
-rw-r--r--libFDK/src/FDK_tools_rom.cpp198
-rw-r--r--libMpegTPDec/src/tpdec_asc.cpp135
-rw-r--r--libMpegTPDec/src/tpdec_drm.cpp146
-rw-r--r--libMpegTPDec/src/tpdec_drm.h194
-rw-r--r--libMpegTPDec/src/tpdec_lib.cpp27
-rw-r--r--libMpegTPDec/src/version2
-rw-r--r--libSBRdec/include/sbrdecoder.h3
-rw-r--r--libSBRdec/src/env_calc.cpp204
-rw-r--r--libSBRdec/src/env_dec.cpp4
-rw-r--r--libSBRdec/src/env_extr.cpp4
-rw-r--r--libSBRdec/src/env_extr.h12
-rw-r--r--libSBRdec/src/sbr_dec.cpp62
-rw-r--r--libSBRdec/src/sbr_dec.h8
-rw-r--r--libSBRdec/src/sbr_ram.h3
-rw-r--r--libSBRdec/src/sbr_rom.cpp11
-rw-r--r--libSBRdec/src/sbr_rom.h3
-rw-r--r--libSBRdec/src/sbrdecoder.cpp177
-rw-r--r--libSYS/src/genericStds.cpp6
26 files changed, 1237 insertions, 142 deletions
diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf
index d388576..458fda1 100644
--- a/documentation/aacDecoder.pdf
+++ b/documentation/aacDecoder.pdf
Binary files differ
diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h
index a0c0854..7ab60f1 100644
--- a/libAACdec/include/aacdecoder_lib.h
+++ b/libAACdec/include/aacdecoder_lib.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -378,6 +378,7 @@ typedef enum {
not exist. */
AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, since the requiered configuration change cannot be
performed. */
+ AAC_DEC_OUTPUT_BUFFER_TOO_SMALL = 0x200C, /*!< The provided output buffer is too small. */
aac_dec_init_error_end = 0x2FFF,
/* Decode errors. Output buffer is valid but concealed. */
diff --git a/libAACdec/src/aac_rom.cpp b/libAACdec/src/aac_rom.cpp
index 607cb3b..f3c9b5a 100644
--- a/libAACdec/src/aac_rom.cpp
+++ b/libAACdec/src/aac_rom.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -167,6 +167,36 @@ const SCHAR ExponentTable [4][14] =
} ;
+/* 41 scfbands */
+static const SHORT sfb_96_1024[42] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 48, 52, 56, 64, 72, 80, 88, 96, 108, 120, 132, 144,
+ 156, 172, 188, 212, 240, 276, 320, 384, 448, 512, 576, 640,
+ 704, 768, 832, 896, 960, 1024
+};
+/* 12 scfbands */
+static const SHORT sfb_96_128[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92,
+ 128
+};
+
+/* 47 scfbands*/
+static const SHORT sfb_64_1024[48] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52,
+ 56, 64, 72, 80, 88, 100, 112, 124, 140, 156, 172, 192, 216, 240,
+ 268, 304, 344, 384, 424, 464, 504, 544, 584, 624, 664, 704, 744, 784,
+ 824, 864, 904, 944, 984,1024
+};
+
+/* 12 scfbands */
+static const SHORT sfb_64_128[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 128
+};
/* 49 scfbands */
static const SHORT sfb_48_1024[50] = {
@@ -239,6 +269,35 @@ static const SHORT sfb_8_128[16] =
};
+static const SHORT sfb_96_960[42] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 96,
+ 108, 120, 132, 144, 156, 172, 188, 212, 240, 276,
+ 320, 384, 448, 512, 576, 640, 704, 768, 832, 896,
+ 960
+}; /* 40 scfbands */
+
+static const SHORT sfb_96_120[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48,
+ 64, 92, 120
+}; /* 12 scfbands */
+
+static const SHORT sfb_64_960[47] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 100,
+ 112, 124, 140, 156, 172, 192, 216, 240, 268, 304,
+ 344, 384, 424, 464, 504, 544, 584, 624, 664, 704,
+ 744, 784, 824, 864, 904, 944, 960
+}; /* 46 scfbands */
+
+static const SHORT sfb_64_120[13] =
+{
+ 0, 4, 8, 12, 16, 20, 24, 32, 40, 48,
+ 64, 92, 120
+}; /* 12 scfbands */
static const SHORT sfb_48_960[50] =
{
@@ -358,9 +417,9 @@ static const SHORT sfb_24_480[31] =
const SFB_INFO sfbOffsetTables[5][16] =
{
{
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_96_1024, sfb_96_128, 41, 12 },
+ { sfb_96_1024, sfb_96_128, 41, 12 },
+ { sfb_64_1024, sfb_64_128, 47, 12 },
{ sfb_48_1024, sfb_48_128, 49, 14 },
{ sfb_48_1024, sfb_48_128, 49, 14 },
{ sfb_32_1024, sfb_48_128, 51, 14 },
@@ -372,9 +431,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
{ sfb_8_1024, sfb_8_128, 40, 15 },
{ sfb_8_1024, sfb_8_128, 40, 15 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_96_960, sfb_96_120, 40, 12 },
+ { sfb_96_960, sfb_96_120, 40, 12 },
+ { sfb_64_960, sfb_64_120, 46, 12 },
{ sfb_48_960, sfb_48_120, 49, 14 },
{ sfb_48_960, sfb_48_120, 49, 14 },
{ sfb_32_960, sfb_48_120, 49, 14 },
@@ -388,9 +447,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
}, {
{ NULL, NULL, 0, 0 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_48_512, NULL, 36, 0 },
+ { sfb_48_512, NULL, 36, 0 },
+ { sfb_48_512, NULL, 36, 0 },
{ sfb_48_512, NULL, 36, 0 },
{ sfb_48_512, NULL, 36, 0},
{ sfb_32_512, NULL, 37, 0 },
@@ -402,9 +461,9 @@ const SFB_INFO sfbOffsetTables[5][16] =
{ sfb_24_512, NULL, 31, 0 },
{ sfb_24_512, NULL, 31, 0 },
}, {
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
- { NULL, NULL, 0, 0 },
+ { sfb_48_480, NULL, 35, 0 },
+ { sfb_48_480, NULL, 35, 0 },
+ { sfb_48_480, NULL, 35, 0 },
{ sfb_48_480, NULL, 35, 0 },
{ sfb_48_480, NULL, 35, 0 },
{ sfb_32_480, NULL, 37, 0 },
diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp
index 8270f69..579e470 100644
--- a/libAACdec/src/aacdecoder.cpp
+++ b/libAACdec/src/aacdecoder.cpp
@@ -157,6 +157,7 @@ amm-info@iis.fraunhofer.de
#include "conceal.h"
+ #include "FDK_crc.h"
void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self)
@@ -537,8 +538,9 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
previous_element,
elIndex,
self->flags & AC_INDEP );
- /* Enable SBR for implicit SBR signalling. */
- if (sbrError == SBRDEC_OK) {
+ /* Enable SBR for implicit SBR signalling but only if no severe error happend. */
+ if ( (sbrError == SBRDEC_OK)
+ || (sbrError == SBRDEC_PARSE_ERROR) ) {
self->sbrEnabled = 1;
}
} else {
@@ -553,7 +555,7 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
FDKpushBiDirectional(hBs, *count);
*count = 0;
} else {
- /* If this is not a fill element with a known length, we are screwed an no further parsing makes sense. */
+ /* If this is not a fill element with a known length, we are screwed and further parsing makes no sense. */
if (sbrError != SBRDEC_OK) {
self->frameOK = 0;
}
@@ -832,12 +834,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
switch (asc->m_aot) {
case AOT_AAC_LC:
self->streamInfo.profile = 1;
- break;
+
+ case AOT_ER_AAC_SCAL:
+ if (asc->m_sc.m_gaSpecificConfig.m_layer > 0) {
+ /* aac_scalable_extension_element() currently not supported. */
+ return AAC_DEC_UNSUPPORTED_FORMAT;
+ }
case AOT_SBR:
case AOT_PS:
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
+ case AOT_DRM_AAC:
break;
default:
@@ -957,11 +965,20 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
if (asc->m_aot == AOT_ER_AAC_ELD) {
self->flags |= AC_ELD;
+ self->flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; /* Need to set the SBR flag for backward-compatibility
+ reasons. Even if SBR is not supported. */
self->flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
self->flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_LD_MPS : 0;
}
self->flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
self->flags |= (asc->m_epConfig >= 0) ? AC_ER : 0;
+ if ( asc->m_aot == AOT_DRM_AAC ) {
+ self->flags |= AC_DRM|AC_SBRCRC|AC_SCALABLE;
+ }
+ if ( (asc->m_aot == AOT_AAC_SCAL)
+ || (asc->m_aot == AOT_ER_AAC_SCAL) ) {
+ self->flags |= AC_SCALABLE;
+ }
if (asc->m_sbrPresentFlag) {
@@ -1147,6 +1164,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Check sampling frequency */
switch ( self->streamInfo.aacSampleRate ) {
+ case 96000:
+ case 88200:
+ case 64000:
case 16000:
case 12000:
case 11025:
@@ -1475,7 +1495,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* get the remaining bits of this frame */
bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0);
- if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) )
+ if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD|AC_DRM)) )
{
SBR_ERROR err = SBRDEC_OK;
int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE];
@@ -1513,6 +1533,13 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
}
+ if (self->flags & AC_DRM)
+ {
+ if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) {
+ FDKpushBiDirectional(bs, bitCnt);
+ }
+ }
+
if ( ! (self->flags & (AC_USAC|AC_RSVD50|AC_DRM)) )
{
while ( bitCnt > 7 ) {
diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h
index 3541773..25bc35d 100644
--- a/libAACdec/src/aacdecoder.h
+++ b/libAACdec/src/aacdecoder.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -226,6 +226,8 @@ struct AAC_DECODER_INSTANCE {
FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
+ INT_PCM pcmOutputBuffer[(8)*(2048)];
+
};
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp
index b501eb9..8863da5 100644
--- a/libAACdec/src/aacdecoder_lib.cpp
+++ b/libAACdec/src/aacdecoder_lib.cpp
@@ -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 11
+#define AACDECODER_LIB_VL2 17
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#ifdef __ANDROID__
#define AACDECODER_LIB_BUILD_DATE ""
@@ -181,8 +181,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw (
break;
}
/* if baselayer is OK we continue decoding */
- if(layer >= 1){
+ if(layer >= 1){
self->nrOfLayers = layer;
+ err = AAC_DEC_OK;
}
break;
}
@@ -785,8 +786,8 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self)
LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
HANDLE_AACDECODER self,
- INT_PCM *pTimeData,
- const INT timeDataSize,
+ INT_PCM *pTimeData_extern,
+ const INT timeDataSize_extern,
const UINT flags)
{
AAC_DECODER_ERROR ErrorStatus;
@@ -796,12 +797,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
HANDLE_FDK_BITSTREAM hBs;
int fTpInterruption = 0; /* Transport originated interruption detection. */
int fTpConceal = 0; /* Transport originated concealment. */
+ INT_PCM *pTimeData = NULL;
+ INT timeDataSize = 0;
if (self == NULL) {
return AAC_DEC_INVALID_HANDLE;
}
+ pTimeData = self->pcmOutputBuffer;
+ timeDataSize = sizeof(self->pcmOutputBuffer)/sizeof(*self->pcmOutputBuffer);
+
if (flags & AACDEC_INTR) {
self->streamInfo.numLostAccessUnits = 0;
}
@@ -918,7 +924,8 @@ 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;
+ int chIdx, numCoreChannel = self->streamInfo.numChannels;
+ int chOutMapIdx = ((self->chMapIndex==0) && (numCoreChannel<7)) ? numCoreChannel : self->chMapIndex;
/* set params */
sbrDecoder_SetParam ( self->hSbrDecoder,
@@ -978,10 +985,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
if (self->psPossible) {
self->flags |= AC_PS_PRESENT;
- self->channelType[0] = ACT_FRONT;
- self->channelType[1] = ACT_FRONT;
- self->channelIndices[0] = 0;
- self->channelIndices[1] = 1;
+ }
+ for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels; chIdx+=1) {
+ self->channelType[chIdx] = ACT_FRONT;
+ self->channelIndices[chIdx] = chIdx;
}
}
}
@@ -1006,7 +1013,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
self->channelOutputMapping,
(self->limiterEnableCurr) ? &pcmLimiterScale : NULL
);
- if (dmxErr == PCMDMX_INVALID_MODE) {
+ if ( (ErrorStatus == AAC_DEC_OK)
+ && (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;
@@ -1051,6 +1059,19 @@ bail:
/* Update Statistics */
aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits, ErrorStatus);
+ /* Check whether external output buffer is large enough. */
+ if (timeDataSize_extern < self->streamInfo.numChannels*self->streamInfo.frameSize) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ }
+
+ /* Update external output buffer. */
+ if ( IS_OUTPUT_VALID(ErrorStatus) ) {
+ FDKmemcpy(pTimeData_extern, pTimeData, self->streamInfo.numChannels*self->streamInfo.frameSize*sizeof(*pTimeData));
+ }
+ else {
+ FDKmemclear(pTimeData_extern, timeDataSize_extern*sizeof(*pTimeData_extern));
+ }
+
return ErrorStatus;
}
@@ -1120,6 +1141,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info )
/* Set flags */
info->flags = 0
| CAPF_AAC_LC
+ | CAPF_ER_AAC_SCAL
| CAPF_AAC_VCB11
| CAPF_AAC_HCR
| CAPF_AAC_RVLC
@@ -1130,6 +1152,7 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info )
| CAPF_AAC_MPEG4
+ | CAPF_AAC_DRM_BSFORMAT
| CAPF_AAC_1024
| CAPF_AAC_960
diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp
index 9d703cc..2965fa6 100644
--- a/libAACdec/src/block.cpp
+++ b/libAACdec/src/block.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -324,11 +324,11 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs,
if (flags & AC_ER_HCR) {
/* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
- pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
- numLinesInSecIdx++;
if (numLinesInSecIdx >= MAX_SFB_HCR) {
return AAC_DEC_PARSE_ERROR;
}
+ pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
+ numLinesInSecIdx++;
if (
(sect_cb == BOOKSCL) )
{
diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp
index f4b510d..1d8ac7b 100644
--- a/libFDK/src/FDK_core.cpp
+++ b/libFDK/src/FDK_core.cpp
@@ -93,7 +93,7 @@ amm-info@iis.fraunhofer.de
/* FDK tools library info */
#define FDK_TOOLS_LIB_VL0 2
#define FDK_TOOLS_LIB_VL1 3
-#define FDK_TOOLS_LIB_VL2 5
+#define FDK_TOOLS_LIB_VL2 6
#define FDK_TOOLS_LIB_TITLE "FDK Tools"
#ifdef __ANDROID__
#define FDK_TOOLS_LIB_BUILD_DATE ""
diff --git a/libFDK/src/FDK_tools_rom.cpp b/libFDK/src/FDK_tools_rom.cpp
index 49f0ee1..29e37f2 100644
--- a/libFDK/src/FDK_tools_rom.cpp
+++ b/libFDK/src/FDK_tools_rom.cpp
@@ -2236,7 +2236,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = {
ics_info,
ms,
ltp_data_present,
- ltp_data,
+ /* ltp_data, */
global_gain,
section_data,
scale_factor_data,
@@ -2247,7 +2247,7 @@ static const rbd_id_t el_aac_cpe1_epc1[] = {
next_channel,
ltp_data_present,
- ltp_data,
+ /* ltp_data, */
global_gain,
section_data,
scale_factor_data,
@@ -2290,7 +2290,178 @@ static const element_list_t node_aac_cpe_epc1 = {
{ &node_aac_cpe0_epc1, &node_aac_cpe1_epc1 }
};
+/*
+ * AOT = 20
+ * epConfig = 0
+ */
+static const rbd_id_t el_scal_sce_epc0[] = {
+ ics_info, /* ESC 1 */
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ esc2_rvlc, /* ESC 2 */
+ tns_data, /* ESC 3 */
+ spectral_data, /* ESC 4 */
+ end_of_sequence
+};
+
+static const struct element_list node_scal_sce_epc0 = {
+ el_scal_sce_epc0,
+ { NULL, NULL }
+};
+
+static const rbd_id_t el_scal_cpe_epc0[] = {
+ ics_info, /* ESC 0 */
+ ms,
+ tns_data_present, /* ESC 1 (ch 0) */
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ esc2_rvlc, /* ESC 2 (ch 0) */
+ tns_data, /* ESC 3 (ch 0) */
+ spectral_data, /* ESC 4 (ch 0) */
+ next_channel,
+ tns_data_present, /* ESC 1 (ch 1) */
+ ltp_data_present,
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ esc2_rvlc, /* ESC 2 (ch 1) */
+ tns_data, /* ESC 3 (ch 1) */
+ spectral_data, /* ESC 4 (ch 1) */
+ end_of_sequence
+};
+static const struct element_list node_scal_cpe_epc0 = {
+ el_scal_cpe_epc0,
+ { NULL, NULL }
+};
+
+/*
+ * AOT = 20
+ * epConfig = 1
+ */
+static const rbd_id_t el_scal_sce_epc1[] = {
+ ics_info,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ tns_data,
+ spectral_data,
+ end_of_sequence
+};
+
+static const struct element_list node_scal_sce_epc1 = {
+ el_scal_sce_epc1,
+ { NULL, NULL }
+};
+
+static const rbd_id_t el_scal_cpe_epc1[] = {
+ ics_info,
+ ms,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ next_channel,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ next_channel,
+ tns_data,
+ next_channel,
+ tns_data,
+ next_channel,
+ spectral_data,
+ next_channel,
+ spectral_data,
+ end_of_sequence
+};
+
+static const struct element_list node_scal_cpe_epc1 = {
+ el_scal_cpe_epc1,
+ { NULL, NULL }
+};
+
+/*
+ * Pseudo AOT for DRM/DRM+ (similar to AOT 20)
+ * Derived from epConfig = 1
+ */
+static const rbd_id_t el_drm_sce[] = {
+ drmcrc_start_reg,
+ ics_info,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ tns_data,
+ drmcrc_end_reg,
+ spectral_data,
+ end_of_sequence
+};
+
+static const struct element_list node_drm_sce = {
+ el_drm_sce,
+ { NULL, NULL }
+};
+
+static const rbd_id_t el_drm_cpe[] = {
+ drmcrc_start_reg,
+ ics_info,
+ ms,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ next_channel,
+ tns_data_present,
+ ltp_data_present,
+ /* ltp_data, */
+ global_gain,
+ section_data,
+ scale_factor_data,
+ esc1_hcr,
+ next_channel,
+ tns_data,
+ next_channel,
+ tns_data,
+ drmcrc_end_reg,
+ next_channel,
+ spectral_data,
+ next_channel,
+ spectral_data,
+ end_of_sequence
+};
+
+static const struct element_list node_drm_cpe = {
+ el_drm_cpe,
+ { NULL, NULL }
+};
/*
* AOT = 39
@@ -2405,6 +2576,19 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo
return &node_aac_cpe_epc1;
}
break;
+ case AOT_ER_AAC_SCAL:
+ if (nChannels == 1) {
+ if (epConfig <= 0)
+ return &node_scal_sce_epc0;
+ else
+ return &node_scal_sce_epc1;
+ } else {
+ if (epConfig <= 0)
+ return &node_scal_cpe_epc0;
+ else
+ return &node_scal_cpe_epc1;
+ }
+ break;
case AOT_ER_AAC_ELD:
if (nChannels == 1) {
if (epConfig <= 0)
@@ -2417,6 +2601,16 @@ const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epCo
else
return &node_eld_cpe_epc1;
}
+ case AOT_DRM_AAC:
+ case AOT_DRM_SBR:
+ case AOT_DRM_MPEG_PS:
+ FDK_ASSERT(epConfig == 1);
+ if (nChannels == 1) {
+ return &node_drm_sce;
+ } else {
+ return &node_drm_cpe;
+ }
+ break;
default:
break;
}
diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp
index bae271e..96a1b35 100644
--- a/libMpegTPDec/src/tpdec_asc.cpp
+++ b/libMpegTPDec/src/tpdec_asc.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -1126,6 +1126,8 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
if ( 0 != ld_sbr_header(asc, hBs, cb) ) {
return TRANSPORTDEC_PARSE_ERROR;
}
+ } else {
+ return TRANSPORTDEC_UNSUPPORTED_FORMAT;
}
}
esc->m_useLdQmfTimeAlign = 0;
@@ -1146,7 +1148,7 @@ TRANSPORTDEC_ERROR EldSpecificConfig_Parse(
switch (eldExtType) {
default:
- for(cnt=0; cnt<len; cnt++) {
+ for(cnt=0; cnt<eldExtLen; cnt++) {
FDKreadBits(hBs, 8 );
}
break;
@@ -1372,4 +1374,133 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
return (ErrorStatus);
}
+TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
+ CSAudioSpecificConfig *self,
+ HANDLE_FDK_BITSTREAM bs
+ )
+{
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+
+ AudioSpecificConfig_Init(self);
+
+ if ((INT)FDKgetValidBits(bs) < 20) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ else {
+ /* DRM - Audio information data entity - type 9
+ - Short Id 2 bits
+ - Stream Id 2 bits
+ - audio coding 2 bits
+ - SBR flag 1 bit
+ - audio mode 2 bits
+ - audio sampling rate 3 bits
+ - text flag 1 bit
+ - enhancement flag 1 bit
+ - coder field 5 bits
+ - rfa 1 bit */
+
+ int audioCoding, audioMode, cSamplingFreq, coderField, sfIdx, sbrFlag;
+
+ /* Read the SDC field */
+ FDKreadBits(bs,4); /* Short and Stream Id */
+
+ audioCoding = FDKreadBits(bs, 2);
+ sbrFlag = FDKreadBits(bs, 1);
+ audioMode = FDKreadBits(bs, 2);
+ cSamplingFreq = FDKreadBits(bs, 3); /* audio sampling rate */
+
+ FDKreadBits(bs, 2); /* Text and enhancement flag */
+ coderField = FDKreadBits(bs, 5);
+ FDKreadBits(bs, 1); /* rfa */
+
+ /* Evaluate configuration and fill the ASC */
+ switch (cSamplingFreq) {
+ case 0: /* 8 kHz */
+ sfIdx = 11;
+ break;
+ case 1: /* 12 kHz */
+ sfIdx = 9;
+ break;
+ case 2: /* 16 kHz */
+ sfIdx = 8;
+ break;
+ case 3: /* 24 kHz */
+ sfIdx = 6;
+ break;
+ case 5: /* 48 kHz */
+ sfIdx = 3;
+ break;
+ case 4: /* reserved */
+ case 6: /* reserved */
+ case 7: /* reserved */
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ self->m_samplingFrequencyIndex = sfIdx;
+ self->m_samplingFrequency = SamplingRateTable[sfIdx];
+
+ if ( sbrFlag ) {
+ UINT i;
+ int tmp = -1;
+ self->m_sbrPresentFlag = 1;
+ self->m_extensionAudioObjectType = AOT_SBR;
+ self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1;
+ for (i=0; i<(sizeof(SamplingRateTable)/sizeof(SamplingRateTable[0])); i++){
+ if (SamplingRateTable[i] == self->m_extensionSamplingFrequency){
+ tmp = i;
+ break;
+ }
+ }
+ self->m_extensionSamplingFrequencyIndex = tmp;
+ }
+
+ switch (audioCoding) {
+ case 0: /* AAC */
+ self->m_aot = AOT_DRM_AAC ; /* Set pseudo AOT for Drm AAC */
+
+ switch (audioMode) {
+ case 1: /* parametric stereo */
+ self->m_psPresentFlag = 1;
+ case 0: /* mono */
+ self->m_channelConfiguration = 1;
+ break;
+ case 2: /* stereo */
+ self->m_channelConfiguration = 2;
+ break;
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ self->m_vcb11Flag = 1;
+ self->m_hcrFlag = 1;
+ self->m_samplesPerFrame = 960;
+ self->m_epConfig = 1;
+ break;
+ case 1: /* CELP */
+ self->m_aot = AOT_ER_CELP;
+ self->m_channelConfiguration = 1;
+ break;
+ case 2: /* HVXC */
+ self->m_aot = AOT_ER_HVXC;
+ self->m_channelConfiguration = 1;
+ break;
+ case 3: /* reserved */
+ default:
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ self->m_aot = AOT_NONE;
+ break;
+ }
+
+ if (self->m_psPresentFlag && !self->m_sbrPresentFlag) {
+ ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+bail:
+ return (ErrorStatus);
+}
diff --git a/libMpegTPDec/src/tpdec_drm.cpp b/libMpegTPDec/src/tpdec_drm.cpp
new file mode 100644
index 0000000..df319e5
--- /dev/null
+++ b/libMpegTPDec/src/tpdec_drm.cpp
@@ -0,0 +1,146 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/***************************** MPEG-4 AAC Decoder **************************
+
+ Author(s): Christian Griebel
+ Description: DRM transport stuff
+
+******************************************************************************/
+
+#include "tpdec_drm.h"
+
+
+#include "FDK_bitstream.h"
+
+
+
+void drmRead_CrcInit(HANDLE_DRM pDrm) /*!< pointer to drm crc info stucture */
+{
+ FDK_ASSERT(pDrm != NULL);
+
+ FDKcrcInit(&pDrm->crcInfo, 0x001d, 0xFFFF, 8);
+}
+
+int drmRead_CrcStartReg(
+ HANDLE_DRM pDrm, /*!< pointer to drm stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int mBits /*!< number of bits in crc region */
+ )
+{
+ FDK_ASSERT(pDrm != NULL);
+
+ FDKcrcReset(&pDrm->crcInfo);
+
+ pDrm->crcReadValue = FDKreadBits(hBs, 8);
+
+ return ( FDKcrcStartReg(&pDrm->crcInfo, hBs, mBits) );
+
+}
+
+void drmRead_CrcEndReg(
+ HANDLE_DRM pDrm, /*!< pointer to drm crc info stucture */
+ HANDLE_FDK_BITSTREAM hBs, /*!< handle to current bit buffer structure */
+ int reg /*!< crc region */
+ )
+{
+ FDK_ASSERT(pDrm != NULL);
+
+ FDKcrcEndReg(&pDrm->crcInfo, hBs, reg);
+}
+
+TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm )
+{
+ TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
+ USHORT crc;
+
+ crc = FDKcrcGetCRC(&pDrm->crcInfo) ^ 0xFF;
+ if (crc != pDrm->crcReadValue)
+ {
+ return (TRANSPORTDEC_CRC_ERROR);
+ }
+
+ return (ErrorStatus);
+}
+
+
diff --git a/libMpegTPDec/src/tpdec_drm.h b/libMpegTPDec/src/tpdec_drm.h
new file mode 100644
index 0000000..2161b4c
--- /dev/null
+++ b/libMpegTPDec/src/tpdec_drm.h
@@ -0,0 +1,194 @@
+
+/* -----------------------------------------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+ All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
+the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
+This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
+audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
+independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
+of the MPEG specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
+may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
+individually for the purpose of encoding or decoding bit streams in products that are compliant with
+the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
+these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
+software may already be covered under those patent licenses when it is used for those licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
+are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
+applications information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification, are permitted without
+payment of copyright license fees provided that you satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
+your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation and/or other materials
+provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
+You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived from this library without
+prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
+software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
+and the date of any change. For modified versions of the FDK AAC Codec, the term
+"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
+"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
+ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
+respect to this software.
+
+You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
+by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
+"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
+of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
+including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
+or business interruption, however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of this software, even if
+advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------------------------------------- */
+
+/***************************** MPEG-4 AAC Decoder **************************
+
+ Author(s): Josef Hoepfl
+ Description: DRM interface
+
+******************************************************************************/
+
+#ifndef TPDEC_DRM_H
+#define TPDEC_DRM_H
+
+#include "tpdec_lib.h"
+
+
+#include "FDK_crc.h"
+
+typedef struct {
+
+ FDK_CRCINFO crcInfo; /* CRC state info */
+ USHORT crcReadValue; /* CRC value read from bitstream data */
+
+} STRUCT_DRM;
+
+typedef STRUCT_DRM *HANDLE_DRM;
+
+/*!
+ \brief Initialize DRM CRC
+
+ The function initialzes the crc buffer and the crc lookup table.
+
+ \return none
+*/
+void drmRead_CrcInit( HANDLE_DRM pDrm );
+
+/**
+ * \brief Starts CRC region with a maximum number of bits
+ * If mBits is positive zero padding will be used for CRC calculation, if there
+ * are less than mBits bits available.
+ * If mBits is negative no zero padding is done.
+ * If mBits is zero the memory for the buffer is allocated dynamically, the
+ * number of bits is not limited.
+ *
+ * \param pDrm DRM data handle
+ * \param hBs bitstream handle, on which the CRC region referes to
+ * \param mBits max number of bits in crc region to be considered
+ *
+ * \return ID for the created region, -1 in case of an error
+ */
+int drmRead_CrcStartReg(
+ HANDLE_DRM pDrm,
+ HANDLE_FDK_BITSTREAM hBs,
+ int mBits
+ );
+
+/**
+ * \brief Ends CRC region identified by reg
+ *
+ * \param pDrm DRM data handle
+ * \param hBs bitstream handle, on which the CRC region referes to
+ * \param reg CRC regions ID returned by drmRead_CrcStartReg()
+ *
+ * \return none
+ */
+void drmRead_CrcEndReg(
+ HANDLE_DRM pDrm,
+ HANDLE_FDK_BITSTREAM hBs,
+ int reg
+ );
+
+/**
+ * \brief Check CRC
+ *
+ * Checks if the currently calculated CRC matches the CRC field read from the bitstream
+ * Deletes all CRC regions.
+ *
+ * \param pDrm DRM data handle
+ *
+ * \return Returns 0 if they are identical otherwise 1
+ */
+TRANSPORTDEC_ERROR drmRead_CrcCheck( HANDLE_DRM pDrm );
+
+/**
+ * \brief Check if we have a valid DRM frame at the current bitbuffer position
+ *
+ * This function assumes enough bits in buffer for the current frame.
+ * It reads out the header bits to prepare the bitbuffer for the decode loop.
+ * In case the header bits show an invalid bitstream/frame, the whole frame is skipped.
+ *
+ * \param pDrm DRM data handle which is filled with parsed DRM header data
+ * \param bs handle of bitstream from whom the DRM header is read
+ *
+ * \return error status
+ */
+TRANSPORTDEC_ERROR drmRead_DecodeHeader(
+ HANDLE_DRM pDrm,
+ HANDLE_FDK_BITSTREAM bs
+ );
+
+/**
+ * \brief Parse a Drm specific SDC audio config from a given bitstream handle.
+ *
+ * \param pAsc A pointer to an allocated CSAudioSpecificConfig struct.
+ * \param hBs Bitstream handle.
+ *
+ * \return Total element count including all SCE, CPE and LFE.
+ */
+TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse( CSAudioSpecificConfig *pAsc,
+ HANDLE_FDK_BITSTREAM hBs );
+
+
+
+#endif /* TPDEC_DRM_H */
diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp
index 950af64..24f755b 100644
--- a/libMpegTPDec/src/tpdec_lib.cpp
+++ b/libMpegTPDec/src/tpdec_lib.cpp
@@ -102,6 +102,7 @@ amm-info@iis.fraunhofer.de
#include "tpdec_latm.h"
+#include "tpdec_drm.h"
#define MODULE_NAME "transportDec"
@@ -113,6 +114,7 @@ typedef union {
CLatmDemux latm;
+ STRUCT_DRM drm;
} transportdec_parser_t;
@@ -182,6 +184,9 @@ HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const
hInput->numberOfRawDataBlocks = 0;
break;
+ case TT_DRM:
+ drmRead_CrcInit(&hInput->parser.drm);
+ break;
case TT_MP4_LATM_MCP0:
case TT_MP4_LATM_MCP1:
@@ -253,6 +258,18 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *
}
}
break;
+ case TT_DRM:
+ fConfigFound = 1;
+ err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs);
+ if (err == TRANSPORTDEC_OK) {
+ int errC;
+
+ errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]);
+ if (errC != 0) {
+ err = TRANSPORTDEC_PARSE_ERROR;
+ }
+ }
+ break;
}
if (err == TRANSPORTDEC_OK && fConfigFound) {
@@ -1083,6 +1100,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c
break;
case TT_MP4_RAW:
+ case TT_DRM:
/* One Access Unit was filled into buffer.
So get the length out of the buffer. */
hTp->auLength[layer] = FDKgetValidBits(hBs);
@@ -1283,6 +1301,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info )
| CAPF_LATM
| CAPF_LOAS
| CAPF_RAWPACKETS
+ | CAPF_DRM
;
return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */
@@ -1294,6 +1313,8 @@ int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits)
switch (pTp->transportFmt) {
case TT_MP4_ADTS:
return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits);
+ case TT_DRM:
+ return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits);
default:
return 0;
}
@@ -1305,6 +1326,9 @@ void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg)
case TT_MP4_ADTS:
adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg);
break;
+ case TT_DRM:
+ drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg);
+ break;
default:
break;
}
@@ -1321,6 +1345,9 @@ TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)
transportDec_AdjustEndOfAccessUnit(pTp);
}
return adtsRead_CrcCheck(&pTp->parser.adts);
+ case TT_DRM:
+ return drmRead_CrcCheck(&pTp->parser.drm);
+ break;
default:
return TRANSPORTDEC_OK;
}
diff --git a/libMpegTPDec/src/version b/libMpegTPDec/src/version
index 18fc9ba..75e22c9 100644
--- a/libMpegTPDec/src/version
+++ b/libMpegTPDec/src/version
@@ -2,7 +2,7 @@
/* library info */
#define TP_LIB_VL0 2
#define TP_LIB_VL1 3
-#define TP_LIB_VL2 5
+#define TP_LIB_VL2 7
#define TP_LIB_TITLE "MPEG Transport"
#ifdef __ANDROID__
#define TP_LIB_BUILD_DATE ""
diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h
index 174fb5c..3bb9ba3 100644
--- a/libSBRdec/include/sbrdecoder.h
+++ b/libSBRdec/include/sbrdecoder.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -262,6 +262,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self,
* into *count if a payload length is given (byPayLen > 0). If no SBR payload length is
* given (bsPayLen < 0) then the bit stream position on return will be random after this
* function call in case of errors, and any further decoding will be completely pointless.
+ * This function accepts either normal ordered SBR data or reverse ordered DRM SBR data.
*
* \param self SBR decoder handle.
* \param hBs Bit stream handle as data source.
diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp
index ade57fc..fa5330a 100644
--- a/libSBRdec/src/env_calc.cpp
+++ b/libSBRdec/src/env_calc.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -151,13 +151,13 @@ typedef struct
}
ENV_CALC_NRGS;
-/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,
+static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,
SCHAR *filtBuffer_e,
FIXP_DBL *NrgGain,
SCHAR *NrgGain_e,
int subbands);
-/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
+static void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
FIXP_DBL **analysBufferImag,
int lowSubband, int highSubband,
int start_pos, int next_pos,
@@ -165,7 +165,7 @@ ENV_CALC_NRGS;
FIXP_DBL *nrgEst,
SCHAR *nrgEst_e );
-/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
+static void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
FIXP_DBL **analysBufferImag,
int nSfb,
UCHAR *freqBandTable,
@@ -174,13 +174,13 @@ ENV_CALC_NRGS;
FIXP_DBL *nrg_est,
SCHAR *nrg_est_e );
-/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c,
+static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c,
FIXP_DBL tmpNoise, SCHAR tmpNoise_e,
UCHAR sinePresentFlag,
UCHAR sineMapped,
int noNoiseFlag);
-/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs,
+static void calcAvgGain(ENV_CALC_NRGS* nrgs,
int lowSubband,
int highSubband,
FIXP_DBL *sumRef_m,
@@ -188,7 +188,7 @@ ENV_CALC_NRGS;
FIXP_DBL *ptrAvgGain_m,
SCHAR *ptrAvgGain_e);
-/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal,
+static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal,
ENV_CALC_NRGS* nrgs,
UCHAR *ptrHarmIndex,
int lowSubbands,
@@ -196,8 +196,17 @@ ENV_CALC_NRGS;
int scale_change,
int noNoiseFlag,
int *ptrPhaseIndex,
- int fCldfb);
-/*static*/ void adjustTimeSlotHQ(FIXP_DBL *ptrReal,
+ int scale_diff_low);
+
+static void adjustTimeSlotLC(FIXP_DBL *ptrReal,
+ ENV_CALC_NRGS* nrgs,
+ UCHAR *ptrHarmIndex,
+ int lowSubbands,
+ int noSubbands,
+ int scale_change,
+ int noNoiseFlag,
+ int *ptrPhaseIndex);
+static void adjustTimeSlotHQ(FIXP_DBL *ptrReal,
FIXP_DBL *ptrImag,
HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
ENV_CALC_NRGS* nrgs,
@@ -224,7 +233,7 @@ ENV_CALC_NRGS;
Additionally, the flags in harmFlagsPrev are being updated by this function
for the next frame.
*/
-/*static*/ void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
+static void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
int nSfb, /*!< Number of bands in the table */
UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */
int *harmFlagsPrev, /*!< Packed 'addHarmonics' */
@@ -990,7 +999,6 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
/* Prevent the smoothing filter from running on constant levels */
if (j-start_pos < smooth_length)
smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos];
-
else
smooth_ratio = FL2FXCONST_SGL(0.0f);
@@ -1007,7 +1015,8 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
}
else
{
- adjustTimeSlotLC(&analysBufferReal[j][lowSubband],
+ if (flags & SBRDEC_ELD_GRID) {
+ adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband],
pNrgs,
&h_sbr_cal_env->harmIndex,
lowSubband,
@@ -1015,7 +1024,18 @@ calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling
scale_change,
noNoiseFlag,
&h_sbr_cal_env->phaseIndex,
- (flags & SBRDEC_ELD_GRID));
+ EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
+ } else
+ {
+ adjustTimeSlotLC(&analysBufferReal[j][lowSubband],
+ pNrgs,
+ &h_sbr_cal_env->harmIndex,
+ lowSubband,
+ noSubbands,
+ scale_change,
+ noNoiseFlag,
+ &h_sbr_cal_env->phaseIndex);
+ }
}
} // for
@@ -1176,7 +1196,7 @@ resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to env
can be performed.
This function is called once for each envelope before adjusting.
*/
-/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */
+static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */
SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */
FIXP_DBL *nrgGain, /*!< gains for current envelope */
SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */
@@ -1331,7 +1351,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
This function is used when interpolFreq is true.
*/
-/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
+static void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
int lowSubband, /*!< Begin of the SBR frequency range */
int highSubband, /*!< High end of the SBR frequency range */
@@ -1452,7 +1472,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
This function is used when interpolFreq is false.
*/
-/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
+static void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
int nSfb, /*!< Number of scale factor bands */
UCHAR *freqBandTable, /*!< First Subband for each Sfb */
@@ -1585,7 +1605,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
The resulting energy gain is given by mantissa and exponent.
*/
-/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
+static void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
ENV_CALC_NRGS* nrgs,
int i,
@@ -1689,7 +1709,7 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
The result is used as a relative limit for all gains within the
current "limiter band" (a certain frequency range).
*/
-/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs,
+static void calcAvgGain(ENV_CALC_NRGS* nrgs,
int lowSubband, /*!< Begin of the limiter band */
int highSubband, /*!< High end of the limiter band */
FIXP_DBL *ptrSumRef,
@@ -1728,21 +1748,101 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
*ptrSumRef_e = sumRef_e;
}
+static void adjustTimeSlot_EldGrid(
+ FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
+ ENV_CALC_NRGS* nrgs,
+ UCHAR *ptrHarmIndex, /*!< Harmonic index */
+ int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
+ int noSubbands, /*!< Number of QMF subbands */
+ int scale_change, /*!< Number of bits to shift adjusted samples */
+ int noNoiseFlag, /*!< Flag to suppress noise addition */
+ int *ptrPhaseIndex, /*!< Start index to random number array */
+ int scale_diff_low) /*!< */
+{
+ int k;
+ FIXP_DBL signalReal, sbNoise;
+ int tone_count = 0;
+
+ FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
+ FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
+ FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
+
+ int phaseIndex = *ptrPhaseIndex;
+ UCHAR harmIndex = *ptrHarmIndex;
+
+ static const INT harmonicPhase [2][4] = {
+ { 1, 0, -1, 0},
+ { 0, 1, 0, -1}
+ };
+
+ static const FIXP_DBL harmonicPhaseX [2][4] = {
+ { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001) },
+ { FL2FXCONST_DBL(2.0*1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001), FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001) }
+ };
+
+ for (k=0; k < noSubbands; k++) {
+
+ phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
+
+ if( (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) || (noNoiseFlag == 1) ){
+ sbNoise = FL2FXCONST_DBL(0.0f);
+ } else {
+ sbNoise = pNoiseLevel[0];
+ }
+
+ signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change);
+
+ signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)<<4);
+
+ signalReal += pSineLevel[0] * harmonicPhase[0][harmIndex];
+
+ *ptrReal = signalReal;
+
+ if (k == 0) {
+ *(ptrReal-1) += scaleValue(fMultDiv2(harmonicPhaseX[lowSubband&1][harmIndex], pSineLevel[0]), -scale_diff_low) ;
+ if (k < noSubbands - 1) {
+ *(ptrReal) += fMultDiv2(pSineLevel[1], harmonicPhaseX[(lowSubband+1)&1][harmIndex]);
+ }
+ }
+ if (k > 0 && k < noSubbands - 1 && tone_count < 16) {
+ *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1] [harmIndex]);
+ *(ptrReal) += fMultDiv2(pSineLevel[+ 1], harmonicPhaseX [(lowSubband+k+1)&1][harmIndex]);
+ }
+ if (k == noSubbands - 1 && tone_count < 16) {
+ if (k > 0) {
+ *(ptrReal) += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1][harmIndex]);
+ }
+ if (k + lowSubband + 1< 63) {
+ *(ptrReal+1) += fMultDiv2(pSineLevel[0], harmonicPhaseX[(lowSubband+k+1)&1][harmIndex]);
+ }
+ }
+
+ if(pSineLevel[0] != FL2FXCONST_DBL(0.0f)){
+ tone_count++;
+ }
+ ptrReal++;
+ pNoiseLevel++;
+ pGain++;
+ pSineLevel++;
+ }
+
+ *ptrHarmIndex = (harmIndex + 1) & 3;
+ *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
+}
/*!
\brief Amplify one timeslot of the signal with the calculated gains
and add the noisefloor.
*/
-/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
+static void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
ENV_CALC_NRGS* nrgs,
UCHAR *ptrHarmIndex, /*!< Harmonic index */
int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
int noSubbands, /*!< Number of QMF subbands */
int scale_change, /*!< Number of bits to shift adjusted samples */
int noNoiseFlag, /*!< Flag to suppress noise addition */
- int *ptrPhaseIndex, /*!< Start index to random number array */
- int fCldfb) /*!< CLDFB 80 flag */
+ int *ptrPhaseIndex) /*!< Start index to random number array */
{
FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
@@ -1775,41 +1875,10 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++;
-
else if (!noNoiseFlag)
/* Add noisefloor to the amplified signal */
signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
- if (fCldfb) {
-
- if (!(harmIndex&0x1)) {
- /* harmIndex 0,2 */
- signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel;
- *ptrReal++ = signalReal;
- }
- else {
- /* harmIndex 1,3 in combination with freqInvFlag */
- int shift = (int) (scale_change+1);
- shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift);
-
- FIXP_DBL tmp1 = scaleValue( fMultDiv2(C1_CLDFB, sineLevel), -shift );
-
- FIXP_DBL tmp2 = fMultDiv2(C1_CLDFB, sineLevelNext);
-
-
- /* save switch and compare operations and reduce to XOR statement */
- if ( ((harmIndex>>1)&0x1)^freqInvFlag) {
- *(ptrReal-1) += tmp1;
- signalReal -= tmp2;
- } else {
- *(ptrReal-1) -= tmp1;
- signalReal += tmp2;
- }
- *ptrReal++ = signalReal;
- freqInvFlag = !freqInvFlag;
- }
-
- } else
{
if (!(harmIndex&0x1)) {
/* harmIndex 0,2 */
@@ -1933,8 +2002,9 @@ FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output
*ptrHarmIndex = (harmIndex + 1) & 3;
*ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
}
-void adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */
- FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */
+static void adjustTimeSlotHQ(
+ FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */
+ FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */
HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
ENV_CALC_NRGS* nrgs,
int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
@@ -2137,7 +2207,6 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM
UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
int patchBorders[MAX_NUM_PATCHES + 1];
int kx, k2;
- FIXP_DBL temp;
int lowSubband = freqBandTable[0];
int highSubband = freqBandTable[noFreqBands];
@@ -2169,13 +2238,32 @@ ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QM
while (hiLimIndex <= tempNoLim) {
+ FIXP_DBL div_m, oct_m, temp;
+ INT div_e = 0, oct_e = 0, temp_e = 0;
+
k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
kx = workLimiterBandTable[loLimIndex] + lowSubband;
- temp = FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx,k2)); /* Number of octaves */
- temp = fMult(temp, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[limiterBands]);
+ div_m = fDivNorm(k2, kx, &div_e);
+
+ /* calculate number of octaves */
+ oct_m = fLog2(div_m, div_e, &oct_e);
+
+ /* multiply with limiterbands per octave */
+ /* values 1, 1.2, 2, 3 -> scale factor of 2 */
+ temp = fMultNorm(oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], &temp_e);
+
+ /* overall scale factor of temp ist addition of scalefactors from log2 calculation,
+ limiter bands scalefactor (2) and limiter bands multiplication */
+ temp_e += oct_e + 2;
+
+ /* div can be a maximum of 64 (k2 = 64 and kx = 1)
+ -> oct can be a maximum of 6
+ -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum factor of 3)
+ -> we need a scale factor of 5 for comparisson
+ */
+ if (temp >> (5 - temp_e) < FL2FXCONST_DBL (0.49f) >> 5) {
- if (temp < FL2FXCONST_DBL (0.49f)>>5) {
if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) {
workLimiterBandTable[hiLimIndex] = highSubband;
nBands--;
diff --git a/libSBRdec/src/env_dec.cpp b/libSBRdec/src/env_dec.cpp
index 24b2d3b..c65c169 100644
--- a/libSBRdec/src/env_dec.cpp
+++ b/libSBRdec/src/env_dec.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -369,7 +369,7 @@ leanSbrConcealment(HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control d
FIXP_SGL step; /* speed of fade */
int i;
- int currentStartPos = h_prev_data->stopPos - hHeaderData->numberTimeSlots;
+ int currentStartPos = FDKmax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots);
int currentStopPos = hHeaderData->numberTimeSlots;
diff --git a/libSBRdec/src/env_extr.cpp b/libSBRdec/src/env_extr.cpp
index 6cb0b99..dacd951 100644
--- a/libSBRdec/src/env_extr.cpp
+++ b/libSBRdec/src/env_extr.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -327,7 +327,7 @@ sbrGetHeaderData (HANDLE_SBR_HEADER_DATA hHeaderData,
}
/* Look for new settings. IEC 14496-3, 4.6.18.3.1 */
- if(hHeaderData->syncState != SBR_ACTIVE ||
+ if(hHeaderData->syncState < SBR_HEADER ||
lastHeader.startFreq != pBsData->startFreq ||
lastHeader.stopFreq != pBsData->stopFreq ||
lastHeader.freqScale != pBsData->freqScale ||
diff --git a/libSBRdec/src/env_extr.h b/libSBRdec/src/env_extr.h
index ab6b704..0518ea9 100644
--- a/libSBRdec/src/env_extr.h
+++ b/libSBRdec/src/env_extr.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -125,6 +125,7 @@ amm-info@iis.fraunhofer.de
typedef enum
{
HEADER_NOT_PRESENT,
+ HEADER_ERROR,
HEADER_OK,
HEADER_RESET
}
@@ -132,10 +133,10 @@ SBR_HEADER_STATUS;
typedef enum
{
- SBR_NOT_INITIALIZED,
- UPSAMPLING,
- SBR_HEADER,
- SBR_ACTIVE
+ SBR_NOT_INITIALIZED = 0,
+ UPSAMPLING = 1,
+ SBR_HEADER = 2,
+ SBR_ACTIVE = 3
}
SBR_SYNC_STATE;
@@ -179,6 +180,7 @@ typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA;
#define SBRDEC_LOW_POWER 16 /* Flag indicating that Low Power QMF mode shall be used. */
#define SBRDEC_PS_DECODED 32 /* Flag indicating that PS was decoded and rendered. */
#define SBRDEC_LD_MPS_QMF 512 /* Flag indicating that the LD-MPS QMF shall be used. */
+#define SBRDEC_SYNTAX_DRM 2048 /* Flag indicating that DRM30/DRM+ reverse syntax is being used. */
#define SBRDEC_DOWNSAMPLE 8192 /* Flag indicating that the downsampling mode is used. */
#define SBRDEC_FLUSH 16384 /* Flag is used to flush all elements in use. */
#define SBRDEC_FORCE_RESET 32768 /* Flag is used to force a reset of all elements in use. */
diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp
index 1282338..0864348 100644
--- a/libSBRdec/src/sbr_dec.cpp
+++ b/libSBRdec/src/sbr_dec.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -225,7 +225,14 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
}
if (resetAnaQmf) {
- int qmfErr = qmfInitAnalysisFilterBank (
+ QMF_FILTER_BANK prvAnaQmf;
+ int qmfErr;
+
+ /* Store current configuration */
+ FDKmemcpy(&prvAnaQmf, &hSbrDec->AnalysiscQMF, sizeof(QMF_FILTER_BANK));
+
+ /* Reset analysis QMF */
+ qmfErr = qmfInitAnalysisFilterBank (
&hSbrDec->AnalysiscQMF,
hSbrDec->anaQmfStates,
hSbrDec->AnalysiscQMF.no_col,
@@ -234,13 +241,22 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
hSbrDec->AnalysiscQMF.no_channels,
anaQmfFlags | QMF_FLAG_KEEP_STATES
);
+
if (qmfErr != 0) {
- FDK_ASSERT(0);
+ /* Restore old configuration of analysis QMF */
+ FDKmemcpy(&hSbrDec->AnalysiscQMF, &prvAnaQmf, sizeof(QMF_FILTER_BANK));
}
}
if (resetSynQmf) {
- int qmfErr = qmfInitSynthesisFilterBank (
+ QMF_FILTER_BANK prvSynQmf;
+ int qmfErr;
+
+ /* Store current configuration */
+ FDKmemcpy(&prvSynQmf, &hSbrDec->SynthesisQMF, sizeof(QMF_FILTER_BANK));
+
+ /* Reset synthesis QMF */
+ qmfErr = qmfInitSynthesisFilterBank (
&hSbrDec->SynthesisQMF,
hSbrDec->pSynQmfStates,
hSbrDec->SynthesisQMF.no_col,
@@ -251,7 +267,8 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand
);
if (qmfErr != 0) {
- FDK_ASSERT(0);
+ /* Restore old configuration of synthesis QMF */
+ FDKmemcpy(&hSbrDec->SynthesisQMF, &prvSynQmf, sizeof(QMF_FILTER_BANK));
}
}
}
@@ -321,7 +338,8 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */
HANDLE_PS_DEC h_ps_d,
- const UINT flags
+ const UINT flags,
+ const int codecFrameSize
)
{
int i, slot, reserve;
@@ -348,6 +366,33 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
if (flags & SBRDEC_ELD_GRID) {
/* Choose the right low delay filter bank */
changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 );
+
+ /* If the LD-MPS QMF is not available delay the signal by (96-48*ldSbrSamplingRate)
+ * samples according to ISO/IEC 14496-3:2009/FDAM 2:2010(E) chapter 4.5.2.13. */
+ if ( (flags & SBRDEC_LD_MPS_QMF)
+ && (hSbrDec->AnalysiscQMF.flags & QMF_FLAG_CLDFB) )
+ {
+ INT_PCM *pDlyBuf = hSbrDec->coreDelayBuf; /* DLYBUF */
+ int smpl, delay = 96 >> (!(flags & SBRDEC_DOWNSAMPLE) ? 1 : 0);
+ /* Create TMPBUF */
+ C_AALLOC_SCRATCH_START(pcmTemp, INT_PCM, (96));
+ /* Copy delay samples from INBUF to TMPBUF */
+ for (smpl = 0; smpl < delay; smpl += 1) {
+ pcmTemp[smpl] = timeIn[(codecFrameSize-delay+smpl)*strideIn];
+ }
+ /* Move input signal remainder to the very end of INBUF */
+ for (smpl = (codecFrameSize-delay-1)*strideIn; smpl >= 0; smpl -= strideIn) {
+ timeIn[smpl+delay] = timeIn[smpl];
+ }
+ /* Copy delayed samples from last frame from DLYBUF to the very beginning of INBUF */
+ for (smpl = 0; smpl < delay; smpl += 1) {
+ timeIn[smpl*strideIn] = pDlyBuf[smpl];
+ }
+ /* Copy TMPBUF to DLYBUF */
+ FDKmemcpy(pDlyBuf, pcmTemp, delay*sizeof(INT_PCM));
+ /* Destory TMPBUF */
+ C_AALLOC_SCRATCH_END(pcmTemp, INT_PCM, (96));
+ }
}
/*
@@ -761,7 +806,7 @@ createSbrDec (SBR_CHANNEL * hSbrChannel,
{
int qmfErr;
/* Adapted QMF analysis post-twiddles for down-sampled HQ SBR */
- const UINT downSampledFlag = (downsampleFac==2) ? QMF_FLAG_DOWNSAMPLED : 0;
+ const UINT downSampledFlag = (flags & SBRDEC_DOWNSAMPLE) ? QMF_FLAG_DOWNSAMPLED : 0;
qmfErr = qmfInitAnalysisFilterBank (
&hs->AnalysiscQMF,
@@ -836,6 +881,9 @@ createSbrDec (SBR_CHANNEL * hSbrChannel,
}
}
+ /* Clear input delay line */
+ FDKmemclear(hs->coreDelayBuf, (96)*sizeof(INT_PCM));
+
/* assign qmf time slots */
assignTimeSlots( &hSbrChannel->SbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, qmfFlags & QMF_FLAG_LP);
diff --git a/libSBRdec/src/sbr_dec.h b/libSBRdec/src/sbr_dec.h
index 175e7b2..edde637 100644
--- a/libSBRdec/src/sbr_dec.h
+++ b/libSBRdec/src/sbr_dec.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -118,6 +118,9 @@ typedef struct
FIXP_DBL * WorkBuffer1;
FIXP_DBL * WorkBuffer2;
+ /* Delayed time input signal needed to align CLDFD with LD-MPS QMF. */
+ INT_PCM coreDelayBuf[(96)];
+
/* QMF filter states */
FIXP_QAS anaQmfStates[(320)];
FIXP_QSS * pSynQmfStates;
@@ -182,7 +185,8 @@ sbr_dec (HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */
HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */
const int applyProcessing, /*!< Flag for SBR operation */
HANDLE_PS_DEC h_ps_d,
- const UINT flags
+ const UINT flags,
+ const int codecFrameSize
);
diff --git a/libSBRdec/src/sbr_ram.h b/libSBRdec/src/sbr_ram.h
index f12631d..7ab5044 100644
--- a/libSBRdec/src/sbr_ram.h
+++ b/libSBRdec/src/sbr_ram.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -135,6 +135,7 @@ struct SBR_DECODER_INSTANCE
USHORT codecFrameSize;
UCHAR synDownsampleFac;
UCHAR numDelayFrames; /* The current number of additional delay frames used for processing. */
+ UCHAR numFlushedFrames; /* The variable counts the number of frames which are flushed consecutively. */
UINT flags;
diff --git a/libSBRdec/src/sbr_rom.cpp b/libSBRdec/src/sbr_rom.cpp
index e84c3cd..c48ce35 100644
--- a/libSBRdec/src/sbr_rom.cpp
+++ b/libSBRdec/src/sbr_rom.cpp
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -189,6 +189,15 @@ const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4] =
FL2FXCONST_SGL(3.0f / 4.0f)
};
+/*! Constants for calculating the number of limiter bands */
+const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4] =
+{
+ FL2FXCONST_DBL(1.0f / 4.0f),
+ FL2FXCONST_DBL(1.2f / 4.0f),
+ FL2FXCONST_DBL(2.0f / 4.0f),
+ FL2FXCONST_DBL(3.0f / 4.0f)
+};
+
/*! Ratio of old gains and noise levels for the first 4 timeslots of an envelope */
const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4] = {
FL2FXCONST_SGL(0.66666666666666f),
diff --git a/libSBRdec/src/sbr_rom.h b/libSBRdec/src/sbr_rom.h
index c318870..1f800bc 100644
--- a/libSBRdec/src/sbr_rom.h
+++ b/libSBRdec/src/sbr_rom.h
@@ -2,7 +2,7 @@
/* -----------------------------------------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
+© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
All rights reserved.
1. INTRODUCTION
@@ -124,6 +124,7 @@ extern const FIXP_DBL FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRI
extern const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4];
extern const UCHAR FDK_sbrDecoder_sbr_limGains_e[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4];
+extern const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4];
extern const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2];
extern const FIXP_SGL harmonicPhaseX [2][4];
diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp
index e15145a..f9ded54 100644
--- a/libSBRdec/src/sbrdecoder.cpp
+++ b/libSBRdec/src/sbrdecoder.cpp
@@ -128,6 +128,7 @@ amm-info@iis.fraunhofer.de
#include "lpp_tran.h"
#include "transcendent.h"
+#include "FDK_crc.h"
#include "sbrdec_drc.h"
@@ -137,7 +138,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */
#define SBRDECODER_LIB_VL0 2
#define SBRDECODER_LIB_VL1 2
-#define SBRDECODER_LIB_VL2 7
+#define SBRDECODER_LIB_VL2 12
#define SBRDECODER_LIB_TITLE "SBR Decoder"
#ifdef __ANDROID__
#define SBRDECODER_LIB_BUILD_DATE ""
@@ -194,6 +195,33 @@ static void copySbrHeader( HANDLE_SBR_HEADER_DATA hDst, const HANDLE_SBR_HEADER_
hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi;
}
+static int compareSbrHeader( const HANDLE_SBR_HEADER_DATA hHdr1, const HANDLE_SBR_HEADER_DATA hHdr2 )
+{
+ int result = 0;
+
+ /* compare basic data */
+ result |= (hHdr1->syncState != hHdr2->syncState) ? 1 : 0;
+ result |= (hHdr1->status != hHdr2->status) ? 1 : 0;
+ result |= (hHdr1->frameErrorFlag != hHdr2->frameErrorFlag) ? 1 : 0;
+ result |= (hHdr1->numberTimeSlots != hHdr2->numberTimeSlots) ? 1 : 0;
+ result |= (hHdr1->numberOfAnalysisBands != hHdr2->numberOfAnalysisBands) ? 1 : 0;
+ result |= (hHdr1->timeStep != hHdr2->timeStep) ? 1 : 0;
+ result |= (hHdr1->sbrProcSmplRate != hHdr2->sbrProcSmplRate) ? 1 : 0;
+
+ /* compare bitstream data */
+ result |= FDKmemcmp( &hHdr1->bs_data, &hHdr2->bs_data, sizeof(SBR_HEADER_DATA_BS) );
+ result |= FDKmemcmp( &hHdr1->bs_info, &hHdr2->bs_info, sizeof(SBR_HEADER_DATA_BS_INFO) );
+
+ /* compare frequency band data */
+ result |= FDKmemcmp( &hHdr1->freqBandData, &hHdr2->freqBandData, (8+MAX_NUM_LIMITERS+1)*sizeof(UCHAR) );
+ result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableLo, hHdr2->freqBandData.freqBandTableLo, (MAX_FREQ_COEFFS/2+1)*sizeof(UCHAR) );
+ result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableHi, hHdr2->freqBandData.freqBandTableHi, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) );
+ result |= FDKmemcmp( hHdr1->freqBandData.freqBandTableNoise, hHdr2->freqBandData.freqBandTableNoise, (MAX_NOISE_COEFFS+1)*sizeof(UCHAR) );
+ result |= FDKmemcmp( hHdr1->freqBandData.v_k_master, hHdr2->freqBandData.v_k_master, (MAX_FREQ_COEFFS+1)*sizeof(UCHAR) );
+
+ return result;
+}
+
/*!
\brief Reset SBR decoder.
@@ -391,6 +419,7 @@ int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec)
case AOT_PS:
case AOT_ER_AAC_SCAL:
case AOT_ER_AAC_ELD:
+ case AOT_DRM_AAC:
return 1;
default:
return 0;
@@ -463,6 +492,8 @@ SBR_ERROR sbrDecoder_InitElement (
self->flags = 0;
self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0;
+ self->flags |= (coreCodec == AOT_ER_AAC_SCAL) ? SBRDEC_SYNTAX_SCAL : 0;
+ self->flags |= (coreCodec == AOT_DRM_AAC) ? SBRDEC_SYNTAX_SCAL|SBRDEC_SYNTAX_DRM : 0;
/* Init SBR elements */
{
@@ -928,24 +959,73 @@ SBR_ERROR sbrDecoder_Parse(
)
{
SBR_DECODER_ELEMENT *hSbrElement;
- HANDLE_SBR_HEADER_DATA hSbrHeader;
+ HANDLE_SBR_HEADER_DATA hSbrHeader = NULL;
HANDLE_SBR_CHANNEL *pSbrChannel;
SBR_FRAME_DATA *hFrameDataLeft;
SBR_FRAME_DATA *hFrameDataRight;
SBR_ERROR errorStatus = SBRDEC_OK;
- SBR_SYNC_STATE initialSyncState;
SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;
INT startPos;
INT CRCLen = 0;
+ HANDLE_FDK_BITSTREAM hBsOriginal = hBs;
+ FDK_CRCINFO crcInfo; /* shall be used for all other CRCs in the future (TBD) */
+ INT crcReg = 0;
+ USHORT drmSbrCrc = 0;
int stereo;
int fDoDecodeSbrData = 1;
int lastSlot, lastHdrSlot = 0, thisHdrSlot;
+ /* Reverse bits of DRM SBR payload */
+ if ( (self->flags & SBRDEC_SYNTAX_DRM) && *count > 0 )
+ {
+ UCHAR *bsBufferDrm = (UCHAR*)self->workBuffer1;
+ HANDLE_FDK_BITSTREAM hBsBwd = (HANDLE_FDK_BITSTREAM) (bsBufferDrm + (512));
+ int dataBytes, dataBits;
+
+ dataBits = *count;
+
+ if (dataBits > ((512)*8)) {
+ /* do not flip more data than needed */
+ dataBits = (512)*8;
+ }
+
+ dataBytes = (dataBits+7)>>3;
+
+ int j;
+
+ if ((j = (int)FDKgetValidBits(hBs)) != 8) {
+ FDKpushBiDirectional(hBs, (j-8));
+ }
+
+ j = 0;
+ for ( ; dataBytes > 0; dataBytes--)
+ {
+ int i;
+ UCHAR tmpByte;
+ UCHAR buffer = 0x00;
+
+ tmpByte = (UCHAR) FDKreadBits(hBs, 8);
+ for (i = 0; i < 4; i++) {
+ int shift = 2 * i + 1;
+ buffer |= (tmpByte & (0x08>>i)) << shift;
+ buffer |= (tmpByte & (0x10<<i)) >> shift;
+ }
+ bsBufferDrm[j++] = buffer;
+ FDKpushBack(hBs, 16);
+ }
+
+ FDKinitBitStream(hBsBwd, bsBufferDrm, (512), dataBits, BS_READER);
+
+ /* Use reversed data */
+ hBs = hBsBwd;
+ bsPayLen = *count;
+ }
+
/* Remember start position of SBR element */
startPos = FDKgetValidBits(hBs);
@@ -970,7 +1050,6 @@ SBR_ERROR sbrDecoder_Parse(
hFrameDataLeft = &self->pSbrElement[elementIndex]->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
hFrameDataRight = &self->pSbrElement[elementIndex]->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
- initialSyncState = hSbrHeader->syncState;
/* reset PS flag; will be set after PS was found */
self->flags &= ~SBRDEC_PS_DECODED;
@@ -1006,12 +1085,19 @@ SBR_ERROR sbrDecoder_Parse(
*/
if (fDoDecodeSbrData)
{
- if (crcFlag == 1) {
+ if (crcFlag) {
switch (self->coreCodec) {
case AOT_ER_AAC_ELD:
FDKpushFor (hBs, 10);
/* check sbrcrc later: we don't know the payload length now */
break;
+ case AOT_DRM_AAC:
+ drmSbrCrc = (USHORT)FDKreadBits(hBs, 8);
+ /* Setup CRC decoder */
+ FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8);
+ /* Start CRC region */
+ crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
+ break;
default:
CRCLen = bsPayLen - 10; /* change: 0 => i */
if (CRCLen < 0) {
@@ -1056,6 +1142,7 @@ SBR_ERROR sbrDecoder_Parse(
hSbrHeader->syncState = SBR_HEADER;
} else {
hSbrHeader->syncState = SBR_NOT_INITIALIZED;
+ headerStatus = HEADER_ERROR;
}
}
@@ -1105,7 +1192,7 @@ SBR_ERROR sbrDecoder_Parse(
valBits = (INT)FDKgetValidBits(hBs);
}
- if ( crcFlag == 1 ) {
+ if ( crcFlag ) {
switch (self->coreCodec) {
case AOT_ER_AAC_ELD:
{
@@ -1117,6 +1204,14 @@ SBR_ERROR sbrDecoder_Parse(
FDKpushFor(hBs, crcLen);
}
break;
+ case AOT_DRM_AAC:
+ /* End CRC region */
+ FDKcrcEndReg(&crcInfo, hBs, crcReg);
+ /* Check CRC */
+ if ((FDKcrcGetCRC(&crcInfo)^0xFF) != drmSbrCrc) {
+ fDoDecodeSbrData = 0;
+ }
+ break;
default:
break;
}
@@ -1167,8 +1262,25 @@ SBR_ERROR sbrDecoder_Parse(
}
bail:
- if (errorStatus == SBRDEC_OK) {
- if (headerStatus == HEADER_NOT_PRESENT) {
+
+ if ( self->flags & SBRDEC_SYNTAX_DRM )
+ {
+ hBs = hBsOriginal;
+ }
+
+ if ( (errorStatus == SBRDEC_OK)
+ || ( (errorStatus == SBRDEC_PARSE_ERROR)
+ && (headerStatus != HEADER_ERROR) ) )
+ {
+ int useOldHdr = ( (headerStatus == HEADER_NOT_PRESENT)
+ || (headerStatus == HEADER_ERROR) ) ? 1 : 0;
+
+ if (!useOldHdr && (thisHdrSlot != lastHdrSlot)) {
+ useOldHdr |= ( compareSbrHeader( hSbrHeader,
+ &self->sbrHeader[elementIndex][lastHdrSlot] ) == 0 ) ? 1 : 0;
+ }
+
+ if (useOldHdr != 0) {
/* Use the old header for this frame */
hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot;
} else {
@@ -1229,12 +1341,21 @@ sbrDecoder_DecodeElement (
int numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */
if (self->flags & SBRDEC_FLUSH) {
- /* Move frame pointer to the next slot which is up to be decoded/applied next */
- hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1);
- /* Update header and frame data pointer because they have already been set */
- hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]];
- hFrameDataLeft = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
- hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
+ if ( self->numFlushedFrames > self->numDelayFrames ) {
+ int hdrIdx;
+ /* No valid SBR payload available, hence switch to upsampling (in all headers) */
+ for (hdrIdx = 0; hdrIdx < ((1)+1); hdrIdx += 1) {
+ self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING;
+ }
+ }
+ else {
+ /* Move frame pointer to the next slot which is up to be decoded/applied next */
+ hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1);
+ /* Update header and frame data pointer because they have already been set */
+ hSbrHeader = &self->sbrHeader[elementIndex][hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]];
+ hFrameDataLeft = &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
+ hFrameDataRight = &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
+ }
}
/* Update the header error flag */
@@ -1354,7 +1475,8 @@ sbrDecoder_DecodeElement (
&pSbrChannel[0]->prevFrameData,
(hSbrHeader->syncState == SBR_ACTIVE),
h_ps_d,
- self->flags
+ self->flags,
+ codecFrameSize
);
if (stereo) {
@@ -1371,7 +1493,8 @@ sbrDecoder_DecodeElement (
&pSbrChannel[1]->prevFrameData,
(hSbrHeader->syncState == SBR_ACTIVE),
NULL,
- self->flags
+ self->flags,
+ codecFrameSize
);
}
@@ -1387,20 +1510,21 @@ sbrDecoder_DecodeElement (
if ( !(self->flags & SBRDEC_PS_DECODED) ) {
/* A decoder which is able to decode PS has to produce a stereo output even if no PS data is availble. */
/* So copy left channel to right channel. */
+ int copyFrameSize = codecFrameSize * 2 / self->synDownsampleFac;
if (interleaved) {
INT_PCM *ptr;
INT i;
FDK_ASSERT(strideOut == 2);
ptr = timeData;
- for (i = codecFrameSize; i--; )
+ for (i = copyFrameSize>>1; i--; )
{
INT_PCM tmp; /* This temporal variable is required because some compilers can't do *ptr++ = *ptr++ correctly. */
tmp = *ptr++; *ptr++ = tmp;
tmp = *ptr++; *ptr++ = tmp;
}
} else {
- FDKmemcpy( timeData+2*codecFrameSize, timeData, 2*codecFrameSize*sizeof(INT_PCM) );
+ FDKmemcpy( timeData+copyFrameSize, timeData, copyFrameSize*sizeof(INT_PCM) );
}
}
*numOutChannels = 2; /* Output minimum two channels when PS is enabled. */
@@ -1464,14 +1588,23 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
self->flags &= ~SBRDEC_PS_DECODED;
}
+ if ( self->flags & SBRDEC_FLUSH ) {
+ /* flushing is signalized, hence increment the flush frame counter */
+ self->numFlushedFrames++;
+ }
+ else {
+ /* no flushing is signalized, hence reset the flush frame counter */
+ self->numFlushedFrames = 0;
+ }
+
/* Loop over SBR elements */
for (sbrElementNum = 0; sbrElementNum<self->numSbrElements; sbrElementNum++)
{
int numElementChan;
if (psPossible && self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) {
- errorStatus = SBRDEC_UNSUPPORTED_CONFIG;
- goto bail;
+ /* Disable PS and try decoding SBR mono. */
+ psPossible = 0;
}
numElementChan = (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1;
@@ -1579,6 +1712,7 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info )
| CAPF_SBR_HQ
| CAPF_SBR_LP
| CAPF_SBR_PS_MPEG
+ | CAPF_SBR_DRM_BS
| CAPF_SBR_CONCEALMENT
| CAPF_SBR_DRC
;
@@ -1607,6 +1741,9 @@ UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self )
/* Low delay SBR: */
{
outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */
+ if (flags & SBRDEC_LD_MPS_QMF) {
+ outputDelay += 32;
+ }
}
}
else if (!IS_USAC(self->coreCodec)) {
diff --git a/libSYS/src/genericStds.cpp b/libSYS/src/genericStds.cpp
index 53abe06..89c422c 100644
--- a/libSYS/src/genericStds.cpp
+++ b/libSYS/src/genericStds.cpp
@@ -92,14 +92,14 @@ amm-info@iis.fraunhofer.de
#define _CRT_SECURE_NO_WARNINGS
-#include "genericStds.h"
-
#include <math.h>
+#include "genericStds.h"
+
/* library info */
#define SYS_LIB_VL0 1
#define SYS_LIB_VL1 3
-#define SYS_LIB_VL2 7
+#define SYS_LIB_VL2 8
#define SYS_LIB_TITLE "System Integration Library"
#ifdef __ANDROID__
#define SYS_LIB_BUILD_DATE ""