diff options
author | James Dong <jdong@google.com> | 2010-06-23 16:51:39 -0700 |
---|---|---|
committer | James Dong <jdong@google.com> | 2010-06-23 17:12:11 -0700 |
commit | 065d1aff96818df54456053f1574aec8a234d0de (patch) | |
tree | 25a56b897088dc0d984eddc5ecbd9df9a385f2be /media/libstagefright/codecs/aacenc | |
parent | 2439a8d6d99864ba0c2d94f428e6c9ee258cdd45 (diff) | |
download | frameworks_av-065d1aff96818df54456053f1574aec8a234d0de.zip frameworks_av-065d1aff96818df54456053f1574aec8a234d0de.tar.gz frameworks_av-065d1aff96818df54456053f1574aec8a234d0de.tar.bz2 |
Fixed the software AAC encoder
Make sure that each input frame contains at least 1024 samples, as
required by the AAC encoder, and fix the incorrect timestamp.
Change-Id: I344cafe8c89be51d6e64552fab70539990ff6049
Diffstat (limited to 'media/libstagefright/codecs/aacenc')
-rw-r--r-- | media/libstagefright/codecs/aacenc/AACEncoder.cpp | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp index 52204fa..b914023 100644 --- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp +++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp @@ -139,6 +139,8 @@ status_t AACEncoder::start(MetaData *params) { CHECK_EQ(OK, initCheck()); + mNumInputSamples = 0; + mAnchorTimeUs = 0; mFrameCount = 0; mSource->start(params); @@ -205,33 +207,65 @@ status_t AACEncoder::read( buffer->set_range(0, 2); buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); *out = buffer; - mInputBuffer = NULL; ++mFrameCount; return OK; } else if (mFrameCount == 1) { buffer->meta_data()->setInt32(kKeyIsCodecConfig, false); } - // XXX: We assume that the input buffer contains at least - // (actually, exactly) 1024 PCM samples. This needs to be fixed. - if (mInputBuffer == NULL) { - if (mSource->read(&mInputBuffer, options) != OK) { - LOGE("failed to read from input audio source"); - return UNKNOWN_ERROR; + while (mNumInputSamples < kNumSamplesPerFrame) { + if (mInputBuffer == NULL) { + if (mSource->read(&mInputBuffer, options) != OK) { + if (mNumInputSamples == 0) { + return ERROR_END_OF_STREAM; + } + memset(&mInputFrame[mNumInputSamples], + 0, + sizeof(int16_t) * (kNumSamplesPerFrame - mNumInputSamples)); + mNumInputSamples = 0; + break; + } + + size_t align = mInputBuffer->range_length() % sizeof(int16_t); + CHECK_EQ(align, 0); + + int64_t timeUs; + if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { + mAnchorTimeUs = timeUs; + } + } + size_t copy = + (kNumSamplesPerFrame - mNumInputSamples) * sizeof(int16_t); + + if (copy > mInputBuffer->range_length()) { + copy = mInputBuffer->range_length(); } + + memcpy(&mInputFrame[mNumInputSamples], + (const uint8_t *) mInputBuffer->data() + + mInputBuffer->range_offset(), + copy); + + mInputBuffer->set_range( + mInputBuffer->range_offset() + copy, + mInputBuffer->range_length() - copy); + if (mInputBuffer->range_length() == 0) { mInputBuffer->release(); mInputBuffer = NULL; - return ERROR_END_OF_STREAM; } - VO_CODECBUFFER inputData; - memset(&inputData, 0, sizeof(inputData)); - inputData.Buffer = (unsigned char*) mInputBuffer->data(); - inputData.Length = mInputBuffer->range_length(); - CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData)); + mNumInputSamples += copy / sizeof(int16_t); + if (mNumInputSamples >= kNumSamplesPerFrame) { + mNumInputSamples %= kNumSamplesPerFrame; + break; + } } - CHECK(mInputBuffer != NULL); + VO_CODECBUFFER inputData; + memset(&inputData, 0, sizeof(inputData)); + inputData.Buffer = (unsigned char*) mInputFrame; + inputData.Length = kNumSamplesPerFrame * sizeof(int16_t); + CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData)); VO_CODECBUFFER outputData; memset(&outputData, 0, sizeof(outputData)); @@ -239,24 +273,14 @@ status_t AACEncoder::read( memset(&outputInfo, 0, sizeof(outputInfo)); VO_U32 ret = VO_ERR_NONE; - int32_t outputLength = 0; outputData.Buffer = outPtr; outputData.Length = buffer->size(); ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo); - if (ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL) { - outputLength += outputData.Length; - if (ret == VO_ERR_INPUT_BUFFER_SMALL) { // All done - mInputBuffer->release(); - mInputBuffer = NULL; - } - } else { - LOGE("failed to encode the input data 0x%lx", ret); - } - - buffer->set_range(0, outputLength); + CHECK(ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL); + CHECK(outputData.Length != 0); + buffer->set_range(0, outputData.Length); - // Each output frame compresses 1024 input PCM samples. - int64_t timestampUs = ((mFrameCount - 1) * 1000000LL * 1024) / mSampleRate; + int64_t timestampUs = ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate; ++mFrameCount; buffer->meta_data()->setInt64(kKeyTime, timestampUs); |