/*! \brief SBR decoder processing \return SBRDEC_OK if successfull, else error code */ SBR_ERROR applySBR (SBRDECODER self, SBRBITSTREAM * Bitstr, float *timeData, float *workBufferCore, int *numChannels, int SbrFrameOK, int bDownSample, int bBitstreamDownMix ) { unsigned char i; unsigned char dualMono = 0; int stereo = 0; int CRCLen = 0; int crcEnable = 0; int readHeader = 0; int err = 0; SBR_CHANNEL *SbrChannel = &self->SbrChannel[0]; BIT_BUFFER bitBuf; HANDLE_SBR_HEADER_DATA_DEC hHeaderData = &self->sbr_header; SBR_HEADER_STATUS headerStatus = HEADER_NOT_INITIALIZED; int codecFrameSize = hHeaderData->codecFrameSize; SBR_SYNC_STATE initialSyncState = hHeaderData->syncState; HANDLE_SBR_CONCEAL_DATA hConcealData = &self->SbrConcealData; float * pWorkBuffer1 = &timeData[2*codecFrameSize]; SBR_FRAME_DATA *hFrameDataLeft = (SBR_FRAME_DATA*) pWorkBuffer1; SBR_FRAME_DATA *hFrameDataRight = (SBR_FRAME_DATA*) self->InterimResult; assert( sizeof(SBR_FRAME_DATA) <= MAX_FRAME_SIZE*sizeof(float)); self->SbrChannel->SbrDec.workBuffer2 = workBufferCore; FLC_sub_start("applySBR"); INDIRECT(5); MOVE(9); PTR_INIT(6); /* counting previous operations */ PTR_INIT(1); FUNC(3); DelaySbrBitstr(hConcealData, Bitstr, &SbrFrameOK); INDIRECT(1); BRANCH(1); if (Bitstr->NrElements) { PTR_INIT(6); /* Bitstr->sbrElement[] SbrChannel[] hHeaderData hFrameDataLeft hFrameDataRight bitBuf */ INDIRECT(1); LOOP(1); for (i=0; i<Bitstr->NrElements; i++) { /* Save last error flag */ MOVE(1); hHeaderData->prevFrameErrorFlag = hHeaderData->frameErrorFlag; ADD(1); BRANCH(1); if (Bitstr->NrElements == 2) { MOVE(1); dualMono = 1; } else { BRANCH(2); switch (Bitstr->sbrElement[i].ElementID) { case SBR_ID_SCE: MOVE(1); stereo = 0; break; case SBR_ID_CPE: MOVE(1); stereo = 1; break; default: MOVE(1); SbrFrameOK = 0; } } MULT(1); FUNC(3); initBitBuffer (&bitBuf, Bitstr->sbrElement[i].Data, Bitstr->sbrElement[i].Payload * 8) ; FUNC(2); getbits (&bitBuf, LEN_NIBBLE); BRANCH(1); if (SbrFrameOK) { ADD(1); BRANCH(1); if (Bitstr->sbrElement[i].ExtensionType == SBR_EXTENSION_CRC) { MOVE(1); crcEnable = 1; ADD(2); MULT(1); CRCLen = 8*(Bitstr->sbrElement[i].Payload-1)+4 - SI_SBR_CRC_BITS; BRANCH(1); if (CRCLen < 0) { MOVE(2); crcEnable = 0; SbrFrameOK = 0; } } BRANCH(1); if (crcEnable) { FUNC(2); SbrFrameOK = SbrCrcCheck (&bitBuf, CRCLen); } FUNC(2); readHeader = getbits (&bitBuf, 1); BRANCH(1); if (SbrFrameOK){ int lr; FUNC(1); if (readHeader) { FUNC(3); headerStatus = sbrGetHeaderData (hHeaderData, &bitBuf, (SBR_ELEMENT_ID)Bitstr->sbrElement[i].ElementID); ADD(1); BRANCH(1); if (headerStatus == HEADER_NOT_INITIALIZED) { FLC_sub_end(); return SBRDEC_NOT_INITIALIZED; } ADD(1); BRANCH(1); if (headerStatus == HEADER_RESET) { FUNC(1); err = resetFreqBandTables(hHeaderData); PTR_INIT(1); /* SbrChannel[] */ LOOP(1); for (lr = 0 ; lr < MAXNRSBRCHANNELS; lr++) { INDIRECT(1); PTR_INIT(1); FUNC(1); resetSbrEnvelopeCalc (&(SbrChannel[lr].SbrDec.SbrCalculateEnvelope)); } PTR_INIT(1); /* SbrChannel[] */ LOOP(1); for (lr = 0 ; lr < MAXNRQMFCHANNELS; lr++) { #ifdef NON_BE_BUGFIX PTR_INIT(1); FUNC(5); #else PTR_INIT(1); FUNC(4); #endif err |= resetSbrQMF (&(SbrChannel[lr].SbrDec), hHeaderData, lr, #ifdef NON_BE_BUGFIX *numChannels, #endif SbrChannel[lr].hPrevFrameData); } BRANCH(1); if (err==0) { MOVE(1); hHeaderData->syncState = SBR_ACTIVE; } } } // if (readHeader) ADD(1); LOGIC(1); BRANCH(1); if (err || hHeaderData->syncState == SBR_NOT_INITIALIZED) { ADD(1); LOGIC(1); BRANCH(1); if (err && hHeaderData->syncState == SBR_NOT_INITIALIZED) { FLC_sub_end(); return SBRDEC_NOT_INITIALIZED; } SHIFT(1); FUNC(3); initHeaderData( hHeaderData, hHeaderData->outSampleRate >> 1, codecFrameSize); FUNC(1); err = resetFreqBandTables(hHeaderData); MOVE(2); hHeaderData->FreqBandData.lowSubband = NO_ANALYSIS_CHANNELS; hHeaderData->FreqBandData.highSubband = NO_ANALYSIS_CHANNELS; PTR_INIT(1); /* SbrChannel[lr] */ LOOP(1); for (lr = 0 ; lr < MAXNRSBRCHANNELS; lr++) { INDIRECT(1); PTR_INIT(1); FUNC(1); resetSbrEnvelopeCalc (&(SbrChannel[lr].SbrDec.SbrCalculateEnvelope)); } PTR_INIT(1); /* SbrChannel[lr] */ LOOP(1); for (lr = 0 ; lr < MAXNRQMFCHANNELS; lr++) { #ifdef NON_BE_BUGFIX PTR_INIT(1); FUNC(5); #else PTR_INIT(1); FUNC(4); #endif err |= resetSbrQMF (&(SbrChannel[lr].SbrDec), hHeaderData, lr, #ifdef NON_BE_BUGFIX *numChannels, #endif SbrChannel[lr].hPrevFrameData); } MOVE(1); hHeaderData->syncState = UPSAMPLING; } ADD(1); BRANCH(1); if (hHeaderData->syncState == SBR_ACTIVE) { BRANCH(1); if (dualMono) { BRANCH(1); if (i == 0) { BRANCH(1); MOVE(1); hFrameDataLeft->xposCtrl = max(0, SbrChannel[i].hPrevFrameData->xposCtrl); FUNC(4); SbrFrameOK = sbrGetSingleChannelElement(hHeaderData, hFrameDataLeft, NULL, &bitBuf); } else { BRANCH(1); MOVE(1); hFrameDataRight->xposCtrl = max(0, SbrChannel[i].hPrevFrameData->xposCtrl); FUNC(4); SbrFrameOK = sbrGetSingleChannelElement(hHeaderData, hFrameDataRight, NULL, &bitBuf); } } else { BRANCH(1); MOVE(1); hFrameDataLeft->xposCtrl = max(0, SbrChannel[i].hPrevFrameData->xposCtrl); BRANCH(1); if (stereo) { BRANCH(1); MOVE(1); hFrameDataRight->xposCtrl = max(0, SbrChannel[i+1].hPrevFrameData->xposCtrl); FUNC(4); SbrFrameOK = sbrGetChannelPairElement(hHeaderData, hFrameDataLeft, hFrameDataRight, &bitBuf); } else { BRANCH(1); if (bBitstreamDownMix) { MOVE(1); self->ParametricStereoDec.bForceMono = 1; } else { MOVE(1); self->ParametricStereoDec.bForceMono = 0; } FUNC(4); SbrFrameOK = sbrGetSingleChannelElement(hHeaderData, hFrameDataLeft, &self->ParametricStereoDec, &bitBuf); } } { int payloadbits = GetNrBitsRead (&bitBuf); int fillbits = (8 - (payloadbits & 7)) & 7; FUNC(1); ADD(1); LOGIC(2); /* counting previous operations */ ADD(2); MULT(1); BRANCH(1); if ((payloadbits + fillbits) != 8 * Bitstr->sbrElement[i].Payload) { MOVE(1); SbrFrameOK = 0; } } } } } ADD(1); LOGIC(1); BRANCH(1); if (!SbrFrameOK || headerStatus == CONCEALMENT) { MOVE(1); hHeaderData->frameErrorFlag = 1; } }
SBR_ERROR sbrDecoder_Parse( HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, int *count, int bsPayLen, int crcFlag, MP4_ELEMENT_ID prevElement, int elementIndex, int fGlobalIndependencyFlag ) { SBR_DECODER_ELEMENT *hSbrElement; HANDLE_SBR_HEADER_DATA hSbrHeader; 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; int stereo; int fDoDecodeSbrData = 1; int lastSlot, lastHdrSlot = 0, thisHdrSlot; /* Remember start position of SBR element */ startPos = FDKgetValidBits(hBs); /* SBR sanity checks */ if ( self == NULL || self->pSbrElement[elementIndex] == NULL ) { errorStatus = SBRDEC_NOT_INITIALIZED; goto bail; } hSbrElement = self->pSbrElement[elementIndex]; lastSlot = (hSbrElement->useFrameSlot > 0) ? hSbrElement->useFrameSlot-1 : self->numDelayFrames; lastHdrSlot = hSbrElement->useHeaderSlot[lastSlot]; thisHdrSlot = getHeaderSlot( hSbrElement->useFrameSlot, hSbrElement->useHeaderSlot ); /* Get a free header slot not used by frames not processed yet. */ /* Assign the free slot to store a new header if there is one. */ hSbrHeader = &self->sbrHeader[elementIndex][thisHdrSlot]; pSbrChannel = hSbrElement->pSbrChannel; stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0; 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; if (hSbrHeader->status & SBRDEC_HDR_STAT_UPDATE) { /* Got a new header from extern (e.g. from an ASC) */ headerStatus = HEADER_OK; hSbrHeader->status &= ~SBRDEC_HDR_STAT_UPDATE; } else if (thisHdrSlot != lastHdrSlot) { /* Copy the last header into this slot otherwise the header compare will trigger more HEADER_RESETs than needed. */ copySbrHeader( hSbrHeader, &self->sbrHeader[elementIndex][lastHdrSlot] ); } /* Check if bit stream data is valid and matches the element context */ if ( ((prevElement != ID_SCE) && (prevElement != ID_CPE)) || prevElement != hSbrElement->elementID) { /* In case of LFE we also land here, since there is no LFE SBR element (do upsampling only) */ fDoDecodeSbrData = 0; } if (fDoDecodeSbrData) { if ((INT)FDKgetValidBits(hBs) <= 0) { fDoDecodeSbrData = 0; } } /* SBR CRC-check */ if (fDoDecodeSbrData) { if (crcFlag == 1) { switch (self->coreCodec) { case AOT_ER_AAC_ELD: FDKpushFor (hBs, 10); /* check sbrcrc later: we don't know the payload length now */ break; default: CRCLen = bsPayLen - 10; /* change: 0 => i */ if (CRCLen < 0) { fDoDecodeSbrData = 0; } else { fDoDecodeSbrData = SbrCrcCheck (hBs, CRCLen); } break; } } } /* if (fDoDecodeSbrData) */ /* Read in the header data and issue a reset if change occured */ if (fDoDecodeSbrData) { int sbrHeaderPresent; { sbrHeaderPresent = FDKreadBit(hBs); } if ( sbrHeaderPresent ) { headerStatus = sbrGetHeaderData (hSbrHeader, hBs, self->flags, 1); } if (headerStatus == HEADER_RESET) { errorStatus = sbrDecoder_HeaderUpdate( self, hSbrHeader, headerStatus, pSbrChannel, hSbrElement->nChannels ); if (errorStatus == SBRDEC_OK) { hSbrHeader->syncState = SBR_HEADER; } else { hSbrHeader->syncState = SBR_NOT_INITIALIZED; } } if (errorStatus != SBRDEC_OK) { fDoDecodeSbrData = 0; } } /* if (fDoDecodeSbrData) */ /* Print debugging output only if state has changed */ /* read frame data */ if ((hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) { int sbrFrameOk; /* read the SBR element data */ if (stereo) { sbrFrameOk = sbrGetChannelPairElement(hSbrHeader, hFrameDataLeft, hFrameDataRight, hBs, self->flags, self->pSbrElement[elementIndex]->transposerSettings.overlap); } else { if (self->hParametricStereoDec != NULL) { /* update slot index for PS bitstream parsing */ self->hParametricStereoDec->bsLastSlot = self->hParametricStereoDec->bsReadSlot; self->hParametricStereoDec->bsReadSlot = hSbrElement->useFrameSlot; } sbrFrameOk = sbrGetSingleChannelElement(hSbrHeader, hFrameDataLeft, hBs, self->hParametricStereoDec, self->flags, self->pSbrElement[elementIndex]->transposerSettings.overlap); } if (!sbrFrameOk) { fDoDecodeSbrData = 0; } else { INT valBits; if (bsPayLen > 0) { valBits = bsPayLen - ((INT)startPos - (INT)FDKgetValidBits(hBs)); } else { valBits = (INT)FDKgetValidBits(hBs); } if ( crcFlag == 1 ) { switch (self->coreCodec) { case AOT_ER_AAC_ELD: { /* late crc check for eld */ INT payloadbits = (INT)startPos - (INT)FDKgetValidBits(hBs) - startPos; INT crcLen = payloadbits - 10; FDKpushBack(hBs, payloadbits); fDoDecodeSbrData = SbrCrcCheck (hBs, crcLen); FDKpushFor(hBs, crcLen); } break; default: break; } } /* sanity check of remaining bits */ if (valBits < 0) { fDoDecodeSbrData = 0; } else { switch (self->coreCodec) { case AOT_SBR: case AOT_PS: case AOT_AAC_LC: { /* This sanity check is only meaningful with General Audio bitstreams */ int alignBits = valBits & 0x7; if (valBits > alignBits) { fDoDecodeSbrData = 0; } } break; default: /* No sanity check available */ break; } } } } 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) { /* Set error flag for this slot to trigger concealment */ self->pSbrElement[elementIndex]->frameErrorFlag[hSbrElement->useFrameSlot] = 1; errorStatus = SBRDEC_PARSE_ERROR; } else { /* Everything seems to be ok so clear the error flag */ self->pSbrElement[elementIndex]->frameErrorFlag[hSbrElement->useFrameSlot] = 0; } if (!stereo) { /* Turn coupling off explicitely to avoid access to absent right frame data that might occur with corrupt bitstreams. */ hFrameDataLeft->coupling = COUPLING_OFF; } bail: if (errorStatus == SBRDEC_OK) { if (headerStatus == HEADER_NOT_PRESENT) { /* Use the old header for this frame */ hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot; } else { /* Use the new header for this frame */ hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = thisHdrSlot; } /* Move frame pointer to the next slot which is up to be decoded/applied next */ hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1); } *count -= startPos - FDKgetValidBits(hBs); return errorStatus; }