void OmxAacDecoder::ResetDecoder() { if (ipMem && (iAacInitFlag != 0)) { PVMP4AudioDecoderResetBuffer(ipMem); } }
// Initialize the aac reader. int aac_init(audio_decoder_p decoder, void *dec_ext) { decoder->dec_ext = calloc(1, sizeof(tPVMP4AudioDecoderExternal)); RETURN_VAL_IF_FAIL((decoder->dec_ext != NULL), AUDIO_DECODER_ERROR); decoder->dec_mem = calloc(1, PVMP4AudioDecoderGetMemRequirements()); RETURN_VAL_IF_FAIL((decoder->dec_mem != NULL), AUDIO_DECODER_ERROR); *((tPVMP4AudioDecoderExternal *) decoder->dec_ext) = *((tPVMP4AudioDecoderExternal *) dec_ext); PVMP4AudioDecoderResetBuffer(decoder->dec_mem); Int err = PVMP4AudioDecoderInitLibrary((tPVMP4AudioDecoderExternal *) decoder->dec_ext, decoder->dec_mem); RETURN_VAL_IF_FAIL((err == MP4AUDEC_SUCCESS), AUDIO_DECODER_ERROR); return AUDIO_DECODER_OK; }
int aac_decode(char *outbuf, const char *inbuf, int len) { int Status; /* seek to first adts sync */ if( !dec_sync ) { uint8_t *inp = (uint8_t *)inbuf; if( (inp[0] == 0xFF) && ((inp[1] & 0xF6) == 0xF0) ) { dec_sync = 1; } else return 0; } append_inbuf(inbuf, len); /* needed for some stream encoded on neon. */ if( pExt->inputBufferCurrentLength - pExt->inputBufferUsedLength < 256 ) { return 0; } //pExt->pInputBuffer = (uint8_t *)inbuf; pExt->pOutputBuffer = (short *)outbuf; pExt->pOutputBuffer_plus = (short *)(outbuf+4096); //pExt->inputBufferUsedLength=0; //pExt->inputBufferCurrentLength = len; if( !dec_configed ) { Status = PVMP4AudioDecoderConfig(pExt, pMem); /*fprintf(stderr, "config %d. used %d, current %d\n", Status, pExt->inputBufferUsedLength, pExt->inputBufferCurrentLength);*/ } Status = PVMP4AudioDecodeFrame(pExt, pMem); if (MP4AUDEC_SUCCESS == Status || SUCCESS == Status) { /*fprintf(stderr, "[SUCCESS] Status: SUCCESS " "inputBufferUsedLength: %u, " "inputBufferCurrentLength: %u, " "remainderBits: %u, " "frameLength: %u\n", pExt->inputBufferUsedLength, pExt->inputBufferCurrentLength, pExt->remainderBits, pExt->frameLength);*/ if( pExt->frameLength > 0 && !dec_configed ) { dec_configed = 1; } } else { fprintf(stderr, "aac decode error %d\n", Status); fprintf(stderr, "used %d, current %d\n", pExt->inputBufferUsedLength, pExt->inputBufferCurrentLength); #if 1 if( pExt->inputBufferUsedLength > pExt->inputBufferCurrentLength ) { /* this is ridiculous, but does happen.. * try to re-init the decoder. */ dec_sync = 0; dec_configed = 0; pExt->inputBufferUsedLength=0; pExt->inputBufferCurrentLength = 0; PVMP4AudioDecoderResetBuffer(pMem); PVMP4AudioDecoderInitLibrary(pExt, pMem); } #endif return -1; } return pExt->frameLength*4; }
/* ----------------------------------------------------------------------------- CDecoder_AAC ResetDecoderL Stop decoder object. Reset decoder. Parameters: none Return Values: status ----------------------------------------------------------------------------- */ OSCL_EXPORT_REF void CDecoder_AAC::ResetDecoderL() { PVMP4AudioDecoderResetBuffer(pMem); }
status_t AACDecoder::read( MediaBuffer **out, const ReadOptions *options) { /* ** end of aac audio stream in the case of initCheck is not OK, ** avoid abnormal playing later. @Jun 16, 2011. by hbb */ if(mInitCheck != OK) { ALOGE("mInitCheck is not OK, so end aac audio stream"); return ERROR_END_OF_STREAM; } status_t err; *out = NULL; int64_t seekTimeUs; ReadOptions::SeekMode mode; if (options && options->getSeekTo(&seekTimeUs, &mode)) { CHECK(seekTimeUs >= 0); mNumSamplesOutput = 0; if (mInputBuffer) { mInputBuffer->release(); mInputBuffer = NULL; } // Make sure that the next buffer output does not still // depend on fragments from the last one decoded. PVMP4AudioDecoderResetBuffer(mDecoderBuf); } else { seekTimeUs = -1; } repeat: if (mInputBuffer == NULL) { err = mSource->read(&mInputBuffer, options); if (err != OK) { return err; } int64_t timeUs; if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { if(mAnchorTimeUs != timeUs) { mAnchorTimeUs = timeUs; mNumSamplesOutput = 0; } } else { // We must have a new timestamp after seeking. CHECK(seekTimeUs < 0); } } MediaBuffer *buffer; CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), (status_t)OK); mConfig->pInputBuffer = (UChar *)mInputBuffer->data() + mInputBuffer->range_offset(); mConfig->inputBufferCurrentLength = mInputBuffer->range_length(); mConfig->inputBufferMaxLength = 0; mConfig->inputBufferUsedLength = 0; mConfig->remainderBits = 0; mConfig->pOutputBuffer = static_cast<Int16 *>(buffer->data()); mConfig->pOutputBuffer_plus = &mConfig->pOutputBuffer[2048]; #if WRITE_FILE if(aacFp) fwrite(mConfig->pInputBuffer,1, mConfig->inputBufferCurrentLength,aacFp); #endif //ALOGE("inputlen %d input[0] = %x input[1]%x", mConfig->inputBufferCurrentLength,(mConfig->pInputBuffer)[0],(mConfig->pInputBuffer)[1]); Int decoderErr = MP4AUDEC_SUCCESS; if(mConfig->isMutilChannle) { decoderErr = PVMP4AudioDecodeFrameSixChannel(mConfig, mDecoderBuf); } else { decoderErr = PVMP4AudioDecodeFrame(mConfig, mDecoderBuf); } if (mInputBuffer != NULL) { mInputBuffer->set_range( mInputBuffer->range_offset() + mConfig->inputBufferUsedLength, mInputBuffer->range_length() - mConfig->inputBufferUsedLength); if (mInputBuffer->range_length() <= 3) { mInputBuffer->release(); mInputBuffer = NULL; } } //if the input data no enough,will drop this frame inputdata. get the next frame data. if(decoderErr != MP4AUDEC_SUCCESS) { if(mInputBuffer) { mInputBuffer->release(); mInputBuffer = NULL; } if(buffer) { buffer->release(); buffer = NULL; } goto repeat; } /* * AAC+/eAAC+ streams can be signalled in two ways: either explicitly * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual * rate system and the sampling rate in the final output is actually * doubled compared with the core AAC decoder sampling rate. * * Explicit signalling is done by explicitly defining SBR audio object * type in the bitstream. Implicit signalling is done by embedding * SBR content in AAC extension payload specific to SBR, and hence * requires an AAC decoder to perform pre-checks on actual audio frames. * * Thus, we could not say for sure whether a stream is * AAC+/eAAC+ until the first data frame is decoded. */ if (++mNumDecodedBuffers <= 2) { ALOGV("audio/extended audio object type: %d + %d", mConfig->audioObjectType, mConfig->extendedAudioObjectType); ALOGV("aac+ upsampling factor: %d desired channels: %d", mConfig->aacPlusUpsamplingFactor, mConfig->desiredChannels); CHECK(mNumDecodedBuffers > 0); if (mNumDecodedBuffers == 1) { mUpsamplingFactor = mConfig->aacPlusUpsamplingFactor; // Check on the sampling rate to see whether it is changed. int32_t sampleRate; CHECK(mMeta->findInt32(kKeySampleRate, &sampleRate)); ALOGV("--->aac samplerae %d",sampleRate); if (mConfig->samplingRate != sampleRate) { mMeta->setInt32(kKeySampleRate, mConfig->samplingRate); ALOGV("Sample rate was %d Hz, but now is %d Hz", sampleRate, mConfig->samplingRate); buffer->release(); // mInputBuffer->release(); // mInputBuffer = NULL; return INFO_FORMAT_CHANGED; } } else { // mNumDecodedBuffers == 2 if (mConfig->extendedAudioObjectType == MP4AUDIO_AAC_LC || mConfig->extendedAudioObjectType == MP4AUDIO_LTP) { if (mUpsamplingFactor == 2) { // The stream turns out to be not aacPlus mode anyway ALOGV("Disable AAC+/eAAC+ since extended audio object type is %d", mConfig->extendedAudioObjectType); mConfig->aacPlusEnabled = 0; } } else { if (mUpsamplingFactor == 1) { // aacPlus mode does not buy us anything, but to cause // 1. CPU load to increase, and // 2. a half speed of decoding ALOGV("Disable AAC+/eAAC+ since upsampling factor is 1"); mConfig->aacPlusEnabled = 0; } } } } size_t numOutBytes = mConfig->frameLength * sizeof(int16_t) * mConfig->desiredChannels; if (mUpsamplingFactor == 2) { if (mConfig->desiredChannels == 1) { memcpy(&mConfig->pOutputBuffer[1024], &mConfig->pOutputBuffer[2048], numOutBytes * 2); } numOutBytes *= 2; } if (decoderErr != MP4AUDEC_SUCCESS) { ALOGW("AAC decoder returned error %d, substituting silence", decoderErr); memset(buffer->data(), 0, numOutBytes); // Discard input buffer. if(mInputBuffer) { mInputBuffer->release(); mInputBuffer = NULL; } // fall through } buffer->set_range(0, numOutBytes); buffer->meta_data()->setInt64( kKeyTime, mAnchorTimeUs + (mNumSamplesOutput * 1000000) / mConfig->samplingRate); mNumSamplesOutput += mConfig->frameLength; *out = buffer; return OK; }