From af967fcc55656a0d3c2a05982713f1ca43c1252b Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 20 May 2014 17:24:06 -0700 Subject: AAC Decoder: flush/seek improvements Improve flushing and seeking. Add field to the API stream info structure signaling the additional output delay for flushing and delay compensation. Bug 9428126 Change-Id: I808412905563ea3de50a2e77a9b5dfee829cd2ed --- libSBRdec/include/sbrdecoder.h | 2 ++ libSBRdec/src/env_extr.h | 2 ++ libSBRdec/src/sbrdecoder.cpp | 48 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 47 insertions(+), 5 deletions(-) (limited to 'libSBRdec') diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h index cb06dbc..36a4739 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; diff --git a/libSBRdec/src/env_extr.h b/libSBRdec/src/env_extr.h index 5db6d3d..ddbfa18 100644 --- a/libSBRdec/src/env_extr.h +++ b/libSBRdec/src/env_extr.h @@ -179,6 +179,8 @@ 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_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/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index 5734020..bed23c7 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 4 +#define SBRDECODER_LIB_VL2 5 #define SBRDECODER_LIB_TITLE "SBR Decoder" #define SBRDECODER_LIB_BUILD_DATE __DATE__ #define SBRDECODER_LIB_BUILD_TIME __TIME__ @@ -444,6 +444,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 +551,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; } } @@ -728,6 +730,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 +758,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 +771,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: @@ -1119,6 +1140,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 +1223,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]; @@ -1472,6 +1506,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; -- cgit v1.2.3