summaryrefslogtreecommitdiffstats
path: root/libSBRdec/src
diff options
context:
space:
mode:
Diffstat (limited to 'libSBRdec/src')
-rw-r--r--libSBRdec/src/env_extr.h3
-rw-r--r--libSBRdec/src/sbr_ram.cpp14
-rw-r--r--libSBRdec/src/sbr_ram.h4
-rw-r--r--libSBRdec/src/sbrdec_drc.h2
-rw-r--r--libSBRdec/src/sbrdecoder.cpp95
5 files changed, 96 insertions, 22 deletions
diff --git a/libSBRdec/src/env_extr.h b/libSBRdec/src/env_extr.h
index 5db6d3d..ab6b704 100644
--- a/libSBRdec/src/env_extr.h
+++ b/libSBRdec/src/env_extr.h
@@ -179,6 +179,9 @@ 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_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. */
#define SBRDEC_HDR_STAT_RESET 1
#define SBRDEC_HDR_STAT_UPDATE 2
diff --git a/libSBRdec/src/sbr_ram.cpp b/libSBRdec/src/sbr_ram.cpp
index 6ae941f..c1c2499 100644
--- a/libSBRdec/src/sbr_ram.cpp
+++ b/libSBRdec/src/sbr_ram.cpp
@@ -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 */
diff --git a/libSBRdec/src/sbr_ram.h b/libSBRdec/src/sbr_ram.h
index 8fc2dae..f12631d 100644
--- a/libSBRdec/src/sbr_ram.h
+++ b/libSBRdec/src/sbr_ram.h
@@ -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;
diff --git a/libSBRdec/src/sbrdec_drc.h b/libSBRdec/src/sbrdec_drc.h
index 872c6a0..7eed53a 100644
--- a/libSBRdec/src/sbrdec_drc.h
+++ b/libSBRdec/src/sbrdec_drc.h
@@ -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
diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp
index 26b2ea2..16b0bbc 100644
--- a/libSBRdec/src/sbrdecoder.cpp
+++ b/libSBRdec/src/sbrdecoder.cpp
@@ -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 6
#define SBRDECODER_LIB_TITLE "SBR Decoder"
#define SBRDECODER_LIB_BUILD_DATE __DATE__
#define SBRDECODER_LIB_BUILD_TIME __TIME__
@@ -251,8 +251,10 @@ SBR_ERROR sbrDecoder_ResetElement (
if ( sampleRateIn == sampleRateOut ) {
synDownsampleFac = 2;
+ self->flags |= SBRDEC_DOWNSAMPLE;
} else {
synDownsampleFac = 1;
+ self->flags &= ~SBRDEC_DOWNSAMPLE;
}
self->synDownsampleFac = synDownsampleFac;
@@ -428,7 +430,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;
}
@@ -444,6 +446,7 @@ SBR_ERROR sbrDecoder_InitElement (
&& self->coreCodec == coreCodec
&& self->pSbrElement[elementIndex] != NULL
&& self->pSbrElement[elementIndex]->elementID == elementID
+ && !(self->flags & SBRDEC_FORCE_RESET)
)
{
/* Nothing to do */
@@ -550,8 +553,9 @@ bail:
if (nSbrElementsStart < self->numSbrElements) {
/* Free the memory allocated for this element */
sbrDecoder_DestroyElement( self, elementIndex );
- } else if (self->pSbrElement[elementIndex] != NULL) {
- /* Set error flag to trigger concealment */
+ } else if ( (self->pSbrElement[elementIndex] != NULL)
+ && (elementIndex < (8)))
+ { /* Set error flag to trigger concealment */
self->pSbrElement[elementIndex]->frameErrorFlag[self->pSbrElement[elementIndex]->useFrameSlot] = 1;
}
}
@@ -615,7 +619,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;
}
@@ -728,6 +732,24 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self,
}
}
break;
+ case SBR_FLUSH_DATA:
+ if (value != 0) {
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ } else {
+ self->flags |= SBRDEC_FLUSH;
+ }
+ }
+ break;
+ case SBR_CLEAR_HISTORY:
+ if (value != 0) {
+ if (self == NULL) {
+ errorStatus = SBRDEC_NOT_INITIALIZED;
+ } else {
+ self->flags |= SBRDEC_FORCE_RESET;
+ }
+ }
+ break;
case SBR_BS_INTERRUPTION:
{
int elementIndex;
@@ -738,7 +760,8 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self,
}
/* Loop over SBR elements */
- for (elementIndex = 0; elementIndex < self->numSbrElements; elementIndex++)
+ for (elementIndex = 0; elementIndex < self->numSbrElements; elementIndex++) {
+ if (self->pSbrElement[elementIndex] != NULL)
{
HANDLE_SBR_HEADER_DATA hSbrHeader;
int headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
@@ -750,7 +773,7 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self,
This switches off bitstream parsing until a new header arrives. */
hSbrHeader->syncState = UPSAMPLING;
hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
- }
+ } }
}
break;
default:
@@ -767,7 +790,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 +852,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 +897,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;
@@ -1119,6 +1142,10 @@ SBR_ERROR sbrDecoder_Parse(
}
}
}
+ } else {
+ /* The returned bit count will not be the actual payload size since we did not
+ parse the frame data. Return an error so that the caller can react respectively. */
+ errorStatus = SBRDEC_PARSE_ERROR;
}
if (!fDoDecodeSbrData) {
@@ -1198,6 +1225,15 @@ sbrDecoder_DecodeElement (
int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;
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];
+ }
+
/* Update the header error flag */
hSbrHeader->frameErrorFlag = hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot];
@@ -1375,7 +1411,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 )
@@ -1472,6 +1508,10 @@ SBR_ERROR sbrDecoder_Apply ( HANDLE_SBRDECODER self,
+ /* Clear reset and flush flag because everything seems to be done successfully. */
+ self->flags &= ~SBRDEC_FORCE_RESET;
+ self->flags &= ~SBRDEC_FLUSH;
+
bail:
return errorStatus;
@@ -1496,7 +1536,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 );
}
@@ -1544,3 +1584,34 @@ INT sbrDecoder_GetLibInfo( LIB_INFO *info )
return 0;
}
+
+UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self )
+{
+ UINT outputDelay = 0;
+
+ if ( self != NULL) {
+ UINT flags = self->flags;
+
+ /* See chapter 1.6.7.2 of ISO/IEC 14496-3 for the GA-SBR figures below. */
+
+ /* Are we initialized? */
+ if ( (self->numSbrChannels > 0)
+ && (self->numSbrElements > 0) )
+ {
+ /* Add QMF synthesis delay */
+ if ( (flags & SBRDEC_ELD_GRID)
+ && IS_LOWDELAY(self->coreCodec) ) {
+ /* Low delay SBR: */
+ {
+ outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */
+ }
+ }
+ else if (!IS_USAC(self->coreCodec)) {
+ /* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...) branch: */
+ outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 481 : 962;
+ }
+ }
+ }
+
+ return (outputDelay);
+}