mirror of
https://github.com/mstorsjo/fdk-aac.git
synced 2025-02-02 17:06:54 +01:00
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
This commit is contained in:
parent
fb2e845179
commit
af967fcc55
@ -532,7 +532,7 @@ typedef enum
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* These three members are the only really relevant ones for the user. */
|
/* These five members are the only really relevant ones for the user. */
|
||||||
INT sampleRate; /*!< The samplerate in Hz of the fully decoded PCM audio signal (after SBR processing). */
|
INT sampleRate; /*!< The samplerate in Hz of the fully decoded PCM audio signal (after SBR processing). */
|
||||||
INT frameSize; /*!< The frame size of the decoded PCM audio signal. \n
|
INT frameSize; /*!< The frame size of the decoded PCM audio signal. \n
|
||||||
1024 or 960 for AAC-LC \n
|
1024 or 960 for AAC-LC \n
|
||||||
@ -543,7 +543,7 @@ typedef struct
|
|||||||
UCHAR *pChannelIndices; /*!< Audio channel index for each output audio channel.
|
UCHAR *pChannelIndices; /*!< Audio channel index for each output audio channel.
|
||||||
See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a program_config_element() */
|
See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a program_config_element() */
|
||||||
/* Decoder internal members. */
|
/* Decoder internal members. */
|
||||||
INT aacSampleRate; /*!< sampling rate in Hz without SBR (from configuration info). */
|
INT aacSampleRate; /*!< Sampling rate in Hz without SBR (from configuration info). */
|
||||||
INT profile; /*!< MPEG-2 profile (from file header) (-1: not applicable (e. g. MPEG-4)). */
|
INT profile; /*!< MPEG-2 profile (from file header) (-1: not applicable (e. g. MPEG-4)). */
|
||||||
AUDIO_OBJECT_TYPE aot; /*!< Audio Object Type (from ASC): is set to the appropriate value for MPEG-2 bitstreams (e. g. 2 for AAC-LC). */
|
AUDIO_OBJECT_TYPE aot; /*!< Audio Object Type (from ASC): is set to the appropriate value for MPEG-2 bitstreams (e. g. 2 for AAC-LC). */
|
||||||
INT channelConfig; /*!< Channel configuration (0: PCE defined, 1: mono, 2: stereo, ... */
|
INT channelConfig; /*!< Channel configuration (0: PCE defined, 1: mono, 2: stereo, ... */
|
||||||
@ -556,7 +556,9 @@ typedef struct
|
|||||||
AUDIO_OBJECT_TYPE extAot; /*!< Extension Audio Object Type (from ASC) */
|
AUDIO_OBJECT_TYPE extAot; /*!< Extension Audio Object Type (from ASC) */
|
||||||
INT extSamplingRate; /*!< Extension sampling rate in Hz (from ASC) */
|
INT extSamplingRate; /*!< Extension sampling rate in Hz (from ASC) */
|
||||||
|
|
||||||
UINT flags; /*!< Copy if internal flags. Only to be written by the decoder, and only to be read externally. */
|
UINT outputDelay; /*!< The number of samples the output is additionally delayed by the decoder. */
|
||||||
|
|
||||||
|
UINT flags; /*!< Copy of internal flags. Only to be written by the decoder, and only to be read externally. */
|
||||||
|
|
||||||
SCHAR epConfig; /*!< epConfig level (from ASC): only level 0 supported, -1 means no ER (e. g. AOT=2, MPEG-2 AAC, etc.) */
|
SCHAR epConfig; /*!< epConfig level (from ASC): only level 0 supported, -1 means no ER (e. g. AOT=2, MPEG-2 AAC, etc.) */
|
||||||
|
|
||||||
@ -681,11 +683,15 @@ aacDecoder_Fill ( HANDLE_AACDECODER self,
|
|||||||
const UINT bufferSize[],
|
const UINT bufferSize[],
|
||||||
UINT *bytesValid );
|
UINT *bytesValid );
|
||||||
|
|
||||||
#define AACDEC_CONCEAL 1 /*!< Flag for aacDecoder_DecodeFrame(): do not consider new input data. Do concealment. */
|
#define AACDEC_CONCEAL 1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error concealment module \
|
||||||
#define AACDEC_FLUSH 2 /*!< Flag for aacDecoder_DecodeFrame(): Do not consider new input data. Flush filterbanks (output delayed audio). */
|
to generate a substitute signal for one lost frame. New input data will not be
|
||||||
#define AACDEC_INTR 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data discontinuity. Resync any internals as necessary. */
|
considered. */
|
||||||
#define AACDEC_CLRHIST 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history buffers.
|
#define AACDEC_FLUSH 2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all delayed audio \
|
||||||
Caution: This can cause discontinuities in the output signal. */
|
without having new input data. Thus new input data will not be considered.*/
|
||||||
|
#define AACDEC_INTR 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data discontinuity. \
|
||||||
|
Resync any internals as necessary. */
|
||||||
|
#define AACDEC_CLRHIST 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history buffers.\
|
||||||
|
CAUTION: This can cause discontinuities in the output signal. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Decode one audio frame
|
* \brief Decode one audio frame
|
||||||
|
@ -717,6 +717,8 @@ void CStreamInfoInit(CStreamInfo *pStreamInfo)
|
|||||||
pStreamInfo->numChannels = 0;
|
pStreamInfo->numChannels = 0;
|
||||||
pStreamInfo->sampleRate = 0;
|
pStreamInfo->sampleRate = 0;
|
||||||
pStreamInfo->frameSize = 0;
|
pStreamInfo->frameSize = 0;
|
||||||
|
|
||||||
|
pStreamInfo->outputDelay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1184,11 +1186,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
CConcealment_InitChannelData(&self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
|
CConcealment_InitChannelData(&self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
|
||||||
&self->concealCommonData,
|
&self->concealCommonData,
|
||||||
self->streamInfo.aacSamplesPerFrame );
|
self->streamInfo.aacSamplesPerFrame );
|
||||||
/* Clear concealment buffers to get rid of the complete history */
|
|
||||||
FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo.spectralCoefficient, 1024 * sizeof(FIXP_CNCL));
|
|
||||||
FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo.specScale, 8 * sizeof(SHORT));
|
|
||||||
/* Clear overlap-add buffers to avoid clicks. */
|
/* Clear overlap-add buffers to avoid clicks. */
|
||||||
FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->IMdct.overlap.freq, OverlapBufferSize*sizeof(FIXP_DBL));
|
FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer, OverlapBufferSize*sizeof(FIXP_DBL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1508,10 +1507,19 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (err == SBRDEC_OK) {
|
switch (err) {
|
||||||
|
case SBRDEC_PARSE_ERROR:
|
||||||
|
/* Can not go on parsing because we do not
|
||||||
|
know the length of the SBR extension data. */
|
||||||
|
FDKpushFor(bs, bitCnt);
|
||||||
|
bitCnt = 0;
|
||||||
|
break;
|
||||||
|
case SBRDEC_OK:
|
||||||
self->sbrEnabled = 1;
|
self->sbrEnabled = 1;
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
self->frameOK = 0;
|
self->frameOK = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1601,13 +1609,17 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
self->frameOK=0;
|
self->frameOK=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store or restore the number of channels */
|
/* store or restore the number of channels and the corresponding info */
|
||||||
if ( self->frameOK && !(flags &(AACDEC_CONCEAL|AACDEC_FLUSH)) ) {
|
if ( self->frameOK && !(flags &(AACDEC_CONCEAL|AACDEC_FLUSH)) ) {
|
||||||
self->concealChannels = aacChannels; /* store */
|
self->aacChannelsPrev = aacChannels; /* store */
|
||||||
|
FDKmemcpy(self->channelTypePrev, self->channelType, (8)*sizeof(AUDIO_CHANNEL_TYPE)); /* store */
|
||||||
|
FDKmemcpy(self->channelIndicesPrev, self->channelIndices, (8)*sizeof(UCHAR)); /* store */
|
||||||
self->sbrEnabledPrev = self->sbrEnabled;
|
self->sbrEnabledPrev = self->sbrEnabled;
|
||||||
} else {
|
} else {
|
||||||
if (self->aacChannels > 0) {
|
if (self->aacChannels > 0) {
|
||||||
aacChannels = self->concealChannels; /* restore */
|
aacChannels = self->aacChannelsPrev; /* restore */
|
||||||
|
FDKmemcpy(self->channelType, self->channelTypePrev, (8)*sizeof(AUDIO_CHANNEL_TYPE)); /* restore */
|
||||||
|
FDKmemcpy(self->channelIndices, self->channelIndicesPrev, (8)*sizeof(UCHAR)); /* restore */
|
||||||
self->sbrEnabled = self->sbrEnabledPrev;
|
self->sbrEnabled = self->sbrEnabledPrev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1687,6 +1699,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( flags&AACDEC_FLUSH ) {
|
||||||
|
/* Clear pAacDecoderChannelInfo->pSpectralCoefficient because with AACDEC_FLUSH set it contains undefined data. */
|
||||||
|
FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, sizeof(FIXP_DBL)*self->streamInfo.aacSamplesPerFrame);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Conceal defective spectral data
|
Conceal defective spectral data
|
||||||
*/
|
*/
|
||||||
@ -1765,6 +1782,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add additional concealment delay */
|
||||||
|
self->streamInfo.outputDelay += CConcealment_GetDelay(&self->concealCommonData) * self->streamInfo.aacSamplesPerFrame;
|
||||||
|
|
||||||
/* Reorder channel type information tables. */
|
/* Reorder channel type information tables. */
|
||||||
{
|
{
|
||||||
|
@ -198,7 +198,10 @@ struct AAC_DECODER_INSTANCE {
|
|||||||
CAacDecoderCommonData aacCommonData; /*!< Temporal shared data for all channels hooked into pAacDecoderChannelInfo */
|
CAacDecoderCommonData aacCommonData; /*!< Temporal shared data for all channels hooked into pAacDecoderChannelInfo */
|
||||||
|
|
||||||
CConcealParams concealCommonData;
|
CConcealParams concealCommonData;
|
||||||
INT concealChannels;
|
|
||||||
|
INT aacChannelsPrev; /*!< The amount of AAC core channels of the last successful decode call. */
|
||||||
|
AUDIO_CHANNEL_TYPE channelTypePrev[(8)]; /*!< Array holding the channelType values of the last successful decode call. */
|
||||||
|
UCHAR channelIndicesPrev[(8)]; /*!< Array holding the channelIndices values of the last successful decode call. */
|
||||||
|
|
||||||
|
|
||||||
HANDLE_SBRDECODER hSbrDecoder; /*!< SBR decoder handle. */
|
HANDLE_SBRDECODER hSbrDecoder; /*!< SBR decoder handle. */
|
||||||
|
@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
/* Decoder library info */
|
/* Decoder library info */
|
||||||
#define AACDECODER_LIB_VL0 2
|
#define AACDECODER_LIB_VL0 2
|
||||||
#define AACDECODER_LIB_VL1 5
|
#define AACDECODER_LIB_VL1 5
|
||||||
#define AACDECODER_LIB_VL2 7
|
#define AACDECODER_LIB_VL2 8
|
||||||
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
|
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
|
||||||
#define AACDECODER_LIB_BUILD_DATE __DATE__
|
#define AACDECODER_LIB_BUILD_DATE __DATE__
|
||||||
#define AACDECODER_LIB_BUILD_TIME __TIME__
|
#define AACDECODER_LIB_BUILD_TIME __TIME__
|
||||||
@ -842,6 +842,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
|||||||
/* Signal bit stream interruption to other modules if required. */
|
/* Signal bit stream interruption to other modules if required. */
|
||||||
if ( fTpInterruption || (flags & (AACDEC_INTR|AACDEC_CLRHIST)) )
|
if ( fTpInterruption || (flags & (AACDEC_INTR|AACDEC_CLRHIST)) )
|
||||||
{
|
{
|
||||||
|
sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, (flags&AACDEC_CLRHIST));
|
||||||
aacDecoder_SignalInterruption(self);
|
aacDecoder_SignalInterruption(self);
|
||||||
if ( ! (flags & AACDEC_INTR) ) {
|
if ( ! (flags & AACDEC_INTR) ) {
|
||||||
ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
|
ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
|
||||||
@ -857,6 +858,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
|||||||
self->streamInfo.numBadBytes = 0;
|
self->streamInfo.numBadBytes = 0;
|
||||||
self->streamInfo.numTotalBytes = 0;
|
self->streamInfo.numTotalBytes = 0;
|
||||||
}
|
}
|
||||||
|
/* Reset the output delay field. The modules will add their figures one after another. */
|
||||||
|
self->streamInfo.outputDelay = 0;
|
||||||
|
|
||||||
if (self->limiterEnableUser==(UCHAR)-1) {
|
if (self->limiterEnableUser==(UCHAR)-1) {
|
||||||
/* Enbale limiter for all non-lowdelay AOT's. */
|
/* Enbale limiter for all non-lowdelay AOT's. */
|
||||||
@ -916,6 +919,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
|||||||
sbrDecoder_SetParam ( self->hSbrDecoder,
|
sbrDecoder_SetParam ( self->hSbrDecoder,
|
||||||
SBR_SYSTEM_BITSTREAM_DELAY,
|
SBR_SYSTEM_BITSTREAM_DELAY,
|
||||||
self->sbrParams.bsDelay);
|
self->sbrParams.bsDelay);
|
||||||
|
sbrDecoder_SetParam ( self->hSbrDecoder,
|
||||||
|
SBR_FLUSH_DATA,
|
||||||
|
(flags & AACDEC_FLUSH) );
|
||||||
|
|
||||||
if ( self->streamInfo.aot == AOT_ER_AAC_ELD ) {
|
if ( self->streamInfo.aot == AOT_ER_AAC_ELD ) {
|
||||||
/* Configure QMF */
|
/* Configure QMF */
|
||||||
@ -958,6 +964,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
|||||||
self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame << 1;
|
self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame << 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Correct the additional concealment delay figures */
|
||||||
|
self->streamInfo.outputDelay -= self->sbrParams.bsDelay * self->streamInfo.aacSamplesPerFrame;
|
||||||
|
self->streamInfo.outputDelay += self->sbrParams.bsDelay * self->streamInfo.frameSize;
|
||||||
|
|
||||||
if (self->psPossible) {
|
if (self->psPossible) {
|
||||||
self->flags |= AC_PS_PRESENT;
|
self->flags |= AC_PS_PRESENT;
|
||||||
@ -1014,6 +1023,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(
|
|||||||
self->extGainDelay,
|
self->extGainDelay,
|
||||||
self->streamInfo.frameSize
|
self->streamInfo.frameSize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* Announce the additional limiter output delay */
|
||||||
|
self->streamInfo.outputDelay += getLimiterDelay(self->hLimiter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +145,8 @@ typedef enum
|
|||||||
SBR_SYSTEM_BITSTREAM_DELAY, /*!< System: Switch to enable an additional SBR bitstream delay of one frame. */
|
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_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_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. */
|
SBR_BS_INTERRUPTION /*!< Signal bit stream interruption. Value is ignored. */
|
||||||
} SBRDEC_PARAM;
|
} SBRDEC_PARAM;
|
||||||
|
|
||||||
|
@ -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_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_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_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_RESET 1
|
||||||
#define SBRDEC_HDR_STAT_UPDATE 2
|
#define SBRDEC_HDR_STAT_UPDATE 2
|
||||||
|
@ -137,7 +137,7 @@ amm-info@iis.fraunhofer.de
|
|||||||
/* Decoder library info */
|
/* Decoder library info */
|
||||||
#define SBRDECODER_LIB_VL0 2
|
#define SBRDECODER_LIB_VL0 2
|
||||||
#define SBRDECODER_LIB_VL1 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_TITLE "SBR Decoder"
|
||||||
#define SBRDECODER_LIB_BUILD_DATE __DATE__
|
#define SBRDECODER_LIB_BUILD_DATE __DATE__
|
||||||
#define SBRDECODER_LIB_BUILD_TIME __TIME__
|
#define SBRDECODER_LIB_BUILD_TIME __TIME__
|
||||||
@ -444,6 +444,7 @@ SBR_ERROR sbrDecoder_InitElement (
|
|||||||
&& self->coreCodec == coreCodec
|
&& self->coreCodec == coreCodec
|
||||||
&& self->pSbrElement[elementIndex] != NULL
|
&& self->pSbrElement[elementIndex] != NULL
|
||||||
&& self->pSbrElement[elementIndex]->elementID == elementID
|
&& self->pSbrElement[elementIndex]->elementID == elementID
|
||||||
|
&& !(self->flags & SBRDEC_FORCE_RESET)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Nothing to do */
|
/* Nothing to do */
|
||||||
@ -550,8 +551,9 @@ bail:
|
|||||||
if (nSbrElementsStart < self->numSbrElements) {
|
if (nSbrElementsStart < self->numSbrElements) {
|
||||||
/* Free the memory allocated for this element */
|
/* Free the memory allocated for this element */
|
||||||
sbrDecoder_DestroyElement( self, elementIndex );
|
sbrDecoder_DestroyElement( self, elementIndex );
|
||||||
} else if (self->pSbrElement[elementIndex] != NULL) {
|
} else if ( (self->pSbrElement[elementIndex] != NULL)
|
||||||
/* Set error flag to trigger concealment */
|
&& (elementIndex < (8)))
|
||||||
|
{ /* Set error flag to trigger concealment */
|
||||||
self->pSbrElement[elementIndex]->frameErrorFlag[self->pSbrElement[elementIndex]->useFrameSlot] = 1;
|
self->pSbrElement[elementIndex]->frameErrorFlag[self->pSbrElement[elementIndex]->useFrameSlot] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -728,6 +730,24 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case SBR_BS_INTERRUPTION:
|
||||||
{
|
{
|
||||||
int elementIndex;
|
int elementIndex;
|
||||||
@ -738,7 +758,8 @@ SBR_ERROR sbrDecoder_SetParam (HANDLE_SBRDECODER self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Loop over SBR elements */
|
/* 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;
|
HANDLE_SBR_HEADER_DATA hSbrHeader;
|
||||||
int headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
|
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. */
|
This switches off bitstream parsing until a new header arrives. */
|
||||||
hSbrHeader->syncState = UPSAMPLING;
|
hSbrHeader->syncState = UPSAMPLING;
|
||||||
hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
|
hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
|
||||||
}
|
} }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
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) {
|
if (!fDoDecodeSbrData) {
|
||||||
@ -1198,6 +1223,15 @@ sbrDecoder_DecodeElement (
|
|||||||
int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;
|
int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;
|
||||||
int numElementChannels = hSbrElement->nChannels; /* Number of channels of the current SBR element */
|
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 */
|
/* Update the header error flag */
|
||||||
hSbrHeader->frameErrorFlag = hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot];
|
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:
|
bail:
|
||||||
|
|
||||||
return errorStatus;
|
return errorStatus;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user