diff options
Diffstat (limited to 'libSBRdec')
-rw-r--r-- | libSBRdec/include/sbrdecoder.h | 11 | ||||
-rw-r--r-- | libSBRdec/src/env_extr.h | 3 | ||||
-rw-r--r-- | libSBRdec/src/sbr_ram.cpp | 14 | ||||
-rw-r--r-- | libSBRdec/src/sbr_ram.h | 4 | ||||
-rw-r--r-- | libSBRdec/src/sbrdec_drc.h | 2 | ||||
-rw-r--r-- | libSBRdec/src/sbrdecoder.cpp | 95 |
6 files changed, 106 insertions, 23 deletions
diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h index 13707e0..174fb5c 100644 --- a/libSBRdec/include/sbrdecoder.h +++ b/libSBRdec/include/sbrdecoder.h @@ -145,6 +145,8 @@ typedef enum SBR_SYSTEM_BITSTREAM_DELAY, /*!< System: Switch to enable an additional SBR bitstream delay of one frame. */ SBR_QMF_MODE, /*!< Set QMF mode, either complex or low power. */ SBR_LD_QMF_TIME_ALIGN, /*!< Set QMF type, either LD-MPS or CLDFB. Relevant for ELD streams only. */ + SBR_FLUSH_DATA, /*!< Set internal state to flush the decoder with the next process call. */ + SBR_CLEAR_HISTORY, /*!< Clear all internal states (delay lines, QMF states, ...). */ SBR_BS_INTERRUPTION /*!< Signal bit stream interruption. Value is ignored. */ } SBRDEC_PARAM; @@ -308,7 +310,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 ); @@ -329,6 +331,13 @@ SBR_ERROR sbrDecoder_Close ( HANDLE_SBRDECODER *self ); */ INT sbrDecoder_GetLibInfo( LIB_INFO *info ); +/** + * \brief Determine the modules output signal delay in samples. + * \param self SBR decoder handle. + * \return The number of samples signal delay added by the module. + */ +UINT sbrDecoder_GetDelay( const HANDLE_SBRDECODER self ); + #ifdef __cplusplus } 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); +} |