📄 aacwrap.c
字号:
//check if sample_rate and channels are meaning values at all if((ret != kDecoderStatus_NoError) && (ret != kDecoderStatus_MoreData)) { break; } //if they are meaning values, check if they match with previous ones if(CheckBitstreamParams) { //compare params with previous ones if((AACBitstream_p->sampleRate != PreviousSampleRate) || (AACBitstream_p->channels.total != PreviousChannels)) { //lost of synchronization, go to search header again ret = kDecoderStatus_MoreData;// CheckBitstreamParams = 0;// break; } } else { //don't compare params with previous ones, no valid reference values PreviousSampleRate = AACBitstream_p->sampleRate; PreviousChannels = AACBitstream_p->channels.total; CheckBitstreamParams = 1; } if(FRAME_BUFFER_ELEMENT_LENGTH < AACBitstream_p->dataRequired) { AACBitstream_p->dataRequired = 200; ret = kDecoderStatus_MoreData;// CheckBitstreamParams = 0; } //next processing switch (ret) { case kDecoderStatus_NoError: // cannot start decoding if AB is full, as AudioBuffer is used inplace to decode aac if((AudioBuffer_p = AudioBufferHaveSpace(AACBitstream_p->sampleRate)) == NULL) { //output buffer is full NextStateAfterWaitAB = decodingFrames; AACDecoderNextState = waitingAudioBuffer; return decoderWaitingABempty; } // re-set output pointers to consecutive AudioBuffer element AACUpdateOutput(AudioBuffer_p); // Do not leave the loop, there may be more data available for decoding. AACDecoderNextState = decodingFrames; break; case kDecoderStatus_MoreData: // Can't proceed till mode data available, if (!(AACDataEOF || AACDataEOPB)) { break; // there are more data to process } //clear used FB elements FB_clearFrom = GetElementNumber((unsigned char*)(AACBitstream_p->data)); SetEmptyFBE(FB_clearFrom, pBufferElement.en); //if last element not cleared before, then do it here ClearFBElement(pBufferElement.en); if (AACDataEOPB) { AACDecoderCloseBitstream(AACDecoderHandle, AACScratch_p); AACDecoderNextState = notInitialized; break; } else { return decoderEOF; } #if 0 case kDecoderStatus_NoFrameHeader: case kDecoderStatus_BrokenFrame: case kDecoderStatus_ReservedBitRate: case kDecoderStatus_ReservedSamplingFrequency: case kDecoderStatus_UnsupportedFeature: // Assume a false header was detected, continue silently // (hoping to reach a good sync point), but update the // data pointers otherwise we'll detect the same header! break; case kDecoderStatus_InvalidArgument: break;#endif // 0 } //switch ret break; case decodingFrames: // Decoding of copressed data is ongoing. Continue until // - no more compressd data is available // - not enough space in output buffer available // - error conditions AACDataEOPB = 0; switch(AACUpdateBitstream(AACBitstream_p, flag)) { case waitingForData: //not enough data return decoderWaitingFBdata; case dataEOF: //EOF break; case dataReady: //data ready break; case immediateEOF: // request from Controller return decoderEOF_immediate; case dataEOPB: // end of play block (FF/FB) AACDataEOPB = 1; // to wrap and start header decoding break; } // Update bitstream data pointers ret = AACDecodeFrame(AACDecoderHandle, AACScratch_p, AACOutput_p, AACBitstream_p); // set number of DECODED bytes SetDecodedBytes(AACBitstream_p->dataLength - AACBitstream_p->dataOffset); CurrentBitRate = (uint32)GetCurrentBitRate(); GetCurrentPosition(&position); // xid,playlist position.offset = GetDecodedBytes(); time_event.subcode.event_type = _EVENT_TEP_NOEVENT; CurrentFilePosAfterTAG = GetDecodedBytes() - GetCurrentStartOffset() + (CurrentBitRate >> 1); Fragment = ( 1000 * CurrentFilePosAfterTAG /(CurrentBitRate * DECODER_TIME_INTERVAL) ); if (Fragment != LastReportedFragment) { LastReportedFragment = Fragment; pBufferElement.subcode.event_type |= CAPTURE_EVENT_SUBCODE_REL_TIME; } // if error occured before, now attach the last event pBufferElement.subcode.event_type |= unreported_subcode_event_type; if (pBufferElement.subcode.event_type & (CAPTURE_EVENT_SUBCODE_BEGIN_OF_SONG | CAPTURE_EVENT_SUBCODE_REL_TIME) ) {#ifdef APM_PICKUP//APM: time in miliseconds (overflow?): time_event.ms.rel_time = (CurrentFilePosAfterTAG * 1000) / CurrentBitRate; time_event.ms.event_type = pBufferElement.subcode.event_type;#else //STM: calculate time into MSF format: time_event.subcode.event_type = pBufferElement.subcode.event_type; time_event.subcode.q_subcode.q_min = CurrentFilePosAfterTAG / (60*CurrentBitRate); // min; time_event.subcode.q_subcode.q_sec = (CurrentFilePosAfterTAG / CurrentBitRate) % 60; // sec; time_event.subcode.q_subcode.q_frame = 0; // frame; time_event.subcode.q_subcode.q_tno = position.song_number; time_event.subcode.q_subcode.xid = position.xfile; //timeinfo_msf += ((absolute_outcnt % CurrentSampleRateConverterFrequency) * 75) / CurrentSampleRateConverterFrequency; // frame#endif // store event time not to lose it (if error) unreported_subcode_event_type = pBufferElement.subcode.event_type; time_event.subcode.event_subcode = 0; // CA - info for AB to enable/disable de-emphasis pBufferElement.subcode.event_type = _EVENT_TEP_NOEVENT; } //clear used FB elements FB_clearFrom = GetElementNumber((unsigned char*)(AACBitstream_p->data)); FB_clearTill = GetElementNumber((unsigned char*)(AACBitstream_p->data + AACBitstream_p->dataOffset)); SetEmptyFBE(FB_clearFrom, FB_clearTill); switch (ret) { case kDecoderStatus_NoError: // check the play mode:#if (DEBUG_INCLUDE_COUNTERS==1) countAACGoodFrames++;#endif if (AACOutput_p->numberOfSamples == 0) { AACDecoderNextState = searchingHeader; break; // nothing to do } else { unsigned int sample = AACOutput_p->numberOfSamples; int16* pL = (int16*)(AACOutput_p->channels[0]) + sample - 1; int32* pDst = (int32*)(AACOutput_p->channels[0]) - 1; if(1 == AACBitstream_p->channels.total) { for (; sample; sample --) { *pDst -- = (*pL --) << 16; *pDst -- = *(pDst + 1); } } else { int16* pR = pL + sample; for (; sample; sample --) { *pDst -- = (*pR --) << 16; *pDst -- = (*pL --) << 16; } } } //some output samples have been generated AudioBufferSetFull(AACOutput_p->numberOfSamples, nextElementFlag, &time_event, &position); unreported_subcode_event_type = 0; nextElementFlag = FT_MIDDLE; AACDecoderNextState = searchingHeader; break; case kDecoderStatus_MoreData: //some output samples may have been generated if (AACOutput_p->numberOfSamples > 0) { AudioBufferSetFull(AACOutput_p->numberOfSamples, nextElementFlag, &time_event, &position); unreported_subcode_event_type = 0; nextElementFlag = FT_MIDDLE; } //clear used FB elements FB_clearFrom = GetElementNumber((unsigned char*)(AACBitstream_p->data)); SetEmptyFBE(FB_clearFrom, pBufferElement.en); //if last element not cleared before, then do it here ClearFBElement(pBufferElement.en); if (AACDataEOPB) { // kDecoderStatus_MoreData because EOPB (Play Block) has been reached (no EOF) AACDecoderCloseBitstream(AACDecoderHandle, AACScratch_p); AACDecoderNextState = notInitialized; break; } return decoderEOF; case kDecoderStatus_MoreSamples: // The decoder has filled AudioBuffer. Empty it and continue with AACDecodeFrame if (AACOutput_p->numberOfSamples == 0) { AACDecoderNextState = searchingHeader; break; // nothing to do } //some output samples have been generated AudioBufferSetFull(AACOutput_p->numberOfSamples, nextElementFlag, &time_event, &position); unreported_subcode_event_type = 0; nextElementFlag = FT_MIDDLE; NextStateAfterWaitAB = decodingFrames; if((AudioBuffer_p=AudioBufferHaveSpace(AACBitstream_p->sampleRate)) == NULL) { //output buffer is full AACDecoderNextState = waitingAudioBuffer; return decoderWaitingABempty; } // re-set output pointers to consecutive AudioBuffer element AACUpdateOutput(AudioBuffer_p); break; case kDecoderStatus_BrokenFrame: case kDecoderStatus_FrameDiscarded: case kDecoderStatus_CRCError: // The only thing we can do about these errors // is to skip to the next frame, just like the normal case, // but also signal to the Controller, who may want to mute the output#if (DEBUG_INCLUDE_COUNTERS==1) countAACBadFrames ++;#endif AACDecoderNextState = searchingHeader; break; case kDecoderStatus_InvalidChannelConfiguration: case kDecoderStatus_TooFewOutputChannels: case kDecoderStatus_InvalidArgument: break; case kDecoderStatus_Fatal_Error: case kDecoderStatus_Fatal_UnsupportedFeature: case kDecoderStatus_Fatal_TooManyChannels: // Cannot proceed, request upper layer to discard the file AACDecoderNextState = fatalError; return decoderFatalError; default: break; } break; case waitingAudioBuffer: // Decoding of compressed data is going on, but the decoder // ran out of space in the AudioBuffer. This means we // decoding data faster than it is being consumed by // the audio hardware. Return to caller to be put to sleep. if((AudioBuffer_p = AudioBufferHaveSpace(AACBitstream_p->sampleRate)) == NULL) { //output buffer is full return decoderWaitingABempty; } // re-set output pointers to consecutive AudioBuffer element AACUpdateOutput(AudioBuffer_p); AACDecoderNextState = NextStateAfterWaitAB; break; default: return decoderFatalError; } //switch AACDecoderNextState } //while}void AACKill(DecoderKillType killType){ if (killType == closeOnly) { AACDecoderCloseBitstream(AACDecoderHandle, AACScratch_p); AACDecoderNextState = notInitialized; }// FREE(AACInstanceState_p);#if (0 == HAVE_SHOCK_MEMORY)// FREE(AACScratch_p);#endif /* HAVE_SHOCK_MEMORY */ INIT_FAST_MALLOC();// AACInstanceState_p = NULL;}#endif // HAVE_AAC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -