AACEncoder.cpp revision caa68a57f0b358b8fbe17447ffa453b9120a8610
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "AACEncoder" 19#include <utils/Log.h> 20 21#include "AACEncoder.h" 22#include "voAAC.h" 23#include "cmnMemory.h" 24 25#include <media/stagefright/MediaBufferGroup.h> 26#include <media/stagefright/MediaDebug.h> 27#include <media/stagefright/MediaDefs.h> 28#include <media/stagefright/MediaErrors.h> 29#include <media/stagefright/MetaData.h> 30 31namespace android { 32 33AACEncoder::AACEncoder(const sp<MediaSource> &source, const sp<MetaData> &meta) 34 : mSource(source), 35 mMeta(meta), 36 mStarted(false), 37 mBufferGroup(NULL), 38 mInputBuffer(NULL), 39 mEncoderHandle(NULL), 40 mApiHandle(NULL), 41 mMemOperator(NULL) { 42} 43 44status_t AACEncoder::initCheck() { 45 CHECK(mApiHandle == NULL && mEncoderHandle == NULL); 46 CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate)); 47 CHECK(mMeta->findInt32(kKeyChannelCount, &mChannels)); 48 CHECK(mMeta->findInt32(kKeyBitRate, &mBitRate)); 49 50 mApiHandle = new VO_AUDIO_CODECAPI; 51 CHECK(mApiHandle); 52 53 if (VO_ERR_NONE != voGetAACEncAPI(mApiHandle)) { 54 LOGE("Failed to get api handle"); 55 return UNKNOWN_ERROR; 56 } 57 58 mMemOperator = new VO_MEM_OPERATOR; 59 CHECK(mMemOperator != NULL); 60 mMemOperator->Alloc = cmnMemAlloc; 61 mMemOperator->Copy = cmnMemCopy; 62 mMemOperator->Free = cmnMemFree; 63 mMemOperator->Set = cmnMemSet; 64 mMemOperator->Check = cmnMemCheck; 65 66 VO_CODEC_INIT_USERDATA userData; 67 memset(&userData, 0, sizeof(userData)); 68 userData.memflag = VO_IMF_USERMEMOPERATOR; 69 userData.memData = (VO_PTR) mMemOperator; 70 if (VO_ERR_NONE != mApiHandle->Init(&mEncoderHandle, VO_AUDIO_CodingAAC, &userData)) { 71 LOGE("Failed to init AAC encoder"); 72 return UNKNOWN_ERROR; 73 } 74 if (OK != setAudioSpecificConfigData()) { 75 LOGE("Failed to configure AAC encoder"); 76 return UNKNOWN_ERROR; 77 } 78 79 // Configure AAC encoder$ 80 AACENC_PARAM params; 81 memset(¶ms, 0, sizeof(params)); 82 params.sampleRate = mSampleRate; 83 params.bitRate = mBitRate; 84 params.nChannels = mChannels; 85 params.adtsUsed = 0; // For MP4 file, don't use adts format$ 86 if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AAC_ENCPARAM, ¶ms)) { 87 LOGE("Failed to set AAC encoder parameters"); 88 return UNKNOWN_ERROR; 89 } 90 91 return OK; 92} 93 94static status_t getSampleRateTableIndex(int32_t sampleRate, int32_t &index) { 95 static const int32_t kSampleRateTable[] = { 96 96000, 88200, 64000, 48000, 44100, 32000, 97 24000, 22050, 16000, 12000, 11025, 8000 98 }; 99 const int32_t tableSize = sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]); 100 for (int32_t i = 0; i < tableSize; ++i) { 101 if (sampleRate == kSampleRateTable[i]) { 102 index = i; 103 return OK; 104 } 105 } 106 107 LOGE("Sampling rate %d bps is not supported", sampleRate); 108 return UNKNOWN_ERROR; 109} 110 111status_t AACEncoder::setAudioSpecificConfigData() { 112 LOGV("setAudioSpecificConfigData: %d hz, %d bps, and %d channels", 113 mSampleRate, mBitRate, mChannels); 114 115 int32_t index; 116 CHECK_EQ(OK, getSampleRateTableIndex(mSampleRate, index)); 117 if (mChannels > 2 || mChannels <= 0) { 118 LOGE("Unsupported number of channels(%d)", mChannels); 119 return UNKNOWN_ERROR; 120 } 121 122 // OMX_AUDIO_AACObjectLC 123 mAudioSpecificConfigData[0] = ((0x02 << 3) | (index >> 1)); 124 mAudioSpecificConfigData[1] = ((index & 0x01) << 7) | (mChannels << 3); 125 return OK; 126} 127 128AACEncoder::~AACEncoder() { 129 if (mStarted) { 130 stop(); 131 } 132} 133 134status_t AACEncoder::start(MetaData *params) { 135 if (mStarted) { 136 LOGW("Call start() when encoder already started"); 137 return OK; 138 } 139 140 mBufferGroup = new MediaBufferGroup; 141 mBufferGroup->add_buffer(new MediaBuffer(2048)); 142 143 CHECK_EQ(OK, initCheck()); 144 145 mNumInputSamples = 0; 146 mAnchorTimeUs = 0; 147 mFrameCount = 0; 148 mSource->start(params); 149 150 mStarted = true; 151 152 return OK; 153} 154 155status_t AACEncoder::stop() { 156 if (!mStarted) { 157 LOGW("Call stop() when encoder has not started"); 158 return OK; 159 } 160 161 if (mInputBuffer) { 162 mInputBuffer->release(); 163 mInputBuffer = NULL; 164 } 165 166 delete mBufferGroup; 167 mBufferGroup = NULL; 168 169 mSource->stop(); 170 171 if (mEncoderHandle) { 172 CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle)); 173 mEncoderHandle = NULL; 174 } 175 delete mApiHandle; 176 mApiHandle = NULL; 177 178 mStarted = false; 179 180 return OK; 181} 182 183sp<MetaData> AACEncoder::getFormat() { 184 sp<MetaData> srcFormat = mSource->getFormat(); 185 186 mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 187 188 int64_t durationUs; 189 if (srcFormat->findInt64(kKeyDuration, &durationUs)) { 190 mMeta->setInt64(kKeyDuration, durationUs); 191 } 192 193 mMeta->setCString(kKeyDecoderComponent, "AACEncoder"); 194 195 return mMeta; 196} 197 198status_t AACEncoder::read( 199 MediaBuffer **out, const ReadOptions *options) { 200 status_t err; 201 202 *out = NULL; 203 204 int64_t seekTimeUs; 205 ReadOptions::SeekMode mode; 206 CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode)); 207 208 MediaBuffer *buffer; 209 CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK); 210 uint8_t *outPtr = (uint8_t *)buffer->data(); 211 bool readFromSource = false; 212 int64_t wallClockTimeUs = -1; 213 214 if (mFrameCount == 0) { 215 memcpy(outPtr, mAudioSpecificConfigData, 2); 216 buffer->set_range(0, 2); 217 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 218 *out = buffer; 219 ++mFrameCount; 220 return OK; 221 } else if (mFrameCount == 1) { 222 buffer->meta_data()->setInt32(kKeyIsCodecConfig, false); 223 } 224 225 while (mNumInputSamples < kNumSamplesPerFrame) { 226 if (mInputBuffer == NULL) { 227 if (mSource->read(&mInputBuffer, options) != OK) { 228 if (mNumInputSamples == 0) { 229 buffer->release(); 230 return ERROR_END_OF_STREAM; 231 } 232 memset(&mInputFrame[mNumInputSamples], 233 0, 234 sizeof(int16_t) * (kNumSamplesPerFrame - mNumInputSamples)); 235 mNumInputSamples = 0; 236 break; 237 } 238 239 size_t align = mInputBuffer->range_length() % sizeof(int16_t); 240 CHECK_EQ(align, 0); 241 242 int64_t timeUs; 243 if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) { 244 wallClockTimeUs = timeUs; 245 } 246 if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { 247 mAnchorTimeUs = timeUs; 248 } 249 readFromSource = true; 250 } else { 251 readFromSource = false; 252 } 253 size_t copy = 254 (kNumSamplesPerFrame - mNumInputSamples) * sizeof(int16_t); 255 256 if (copy > mInputBuffer->range_length()) { 257 copy = mInputBuffer->range_length(); 258 } 259 260 memcpy(&mInputFrame[mNumInputSamples], 261 (const uint8_t *) mInputBuffer->data() 262 + mInputBuffer->range_offset(), 263 copy); 264 265 mInputBuffer->set_range( 266 mInputBuffer->range_offset() + copy, 267 mInputBuffer->range_length() - copy); 268 269 if (mInputBuffer->range_length() == 0) { 270 mInputBuffer->release(); 271 mInputBuffer = NULL; 272 } 273 mNumInputSamples += copy / sizeof(int16_t); 274 if (mNumInputSamples >= kNumSamplesPerFrame) { 275 mNumInputSamples %= kNumSamplesPerFrame; 276 break; 277 } 278 } 279 280 VO_CODECBUFFER inputData; 281 memset(&inputData, 0, sizeof(inputData)); 282 inputData.Buffer = (unsigned char*) mInputFrame; 283 inputData.Length = kNumSamplesPerFrame * sizeof(int16_t); 284 CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData)); 285 286 VO_CODECBUFFER outputData; 287 memset(&outputData, 0, sizeof(outputData)); 288 VO_AUDIO_OUTPUTINFO outputInfo; 289 memset(&outputInfo, 0, sizeof(outputInfo)); 290 291 VO_U32 ret = VO_ERR_NONE; 292 outputData.Buffer = outPtr; 293 outputData.Length = buffer->size(); 294 ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo); 295 CHECK(ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL); 296 CHECK(outputData.Length != 0); 297 buffer->set_range(0, outputData.Length); 298 299 int64_t mediaTimeUs = 300 ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate; 301 buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs); 302 if (readFromSource && wallClockTimeUs != -1) { 303 buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs); 304 } 305 ++mFrameCount; 306 307 *out = buffer; 308 return OK; 309} 310 311} // namespace android 312