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/foundation/ADebug.h> 26 #include <media/stagefright/MediaBufferGroup.h> 27 #include <media/stagefright/MediaDefs.h> 28 #include <media/stagefright/MediaErrors.h> 29 #include <media/stagefright/MetaData.h> 30 31 namespace android { 32 33 AACEncoder::AACEncoder(const sp<IMediaSource> &source, const sp<MetaData> &meta) 34 : mSource(source), 35 mMeta(meta), 36 mStarted(false), 37 mBufferGroup(NULL), 38 mInputBuffer(NULL), 39 mInputFrame(NULL), 40 mEncoderHandle(NULL), 41 mApiHandle(NULL), 42 mMemOperator(NULL) { 43 } 44 45 status_t AACEncoder::initCheck() { 46 CHECK(mApiHandle == NULL && mEncoderHandle == NULL); 47 CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate)); 48 CHECK(mMeta->findInt32(kKeyChannelCount, &mChannels)); 49 CHECK(mChannels <= 2 && mChannels >= 1); 50 CHECK(mMeta->findInt32(kKeyBitRate, &mBitRate)); 51 52 mApiHandle = new VO_AUDIO_CODECAPI; 53 CHECK(mApiHandle); 54 55 if (VO_ERR_NONE != voGetAACEncAPI(mApiHandle)) { 56 ALOGE("Failed to get api handle"); 57 return UNKNOWN_ERROR; 58 } 59 60 mMemOperator = new VO_MEM_OPERATOR; 61 CHECK(mMemOperator != NULL); 62 mMemOperator->Alloc = cmnMemAlloc; 63 mMemOperator->Copy = cmnMemCopy; 64 mMemOperator->Free = cmnMemFree; 65 mMemOperator->Set = cmnMemSet; 66 mMemOperator->Check = cmnMemCheck; 67 68 VO_CODEC_INIT_USERDATA userData; 69 memset(&userData, 0, sizeof(userData)); 70 userData.memflag = VO_IMF_USERMEMOPERATOR; 71 userData.memData = (VO_PTR) mMemOperator; 72 if (VO_ERR_NONE != mApiHandle->Init(&mEncoderHandle, VO_AUDIO_CodingAAC, &userData)) { 73 ALOGE("Failed to init AAC encoder"); 74 return UNKNOWN_ERROR; 75 } 76 if (OK != setAudioSpecificConfigData()) { 77 ALOGE("Failed to configure AAC encoder"); 78 return UNKNOWN_ERROR; 79 } 80 81 // Configure AAC encoder$ 82 AACENC_PARAM params; 83 memset(¶ms, 0, sizeof(params)); 84 params.sampleRate = mSampleRate; 85 params.bitRate = mBitRate; 86 params.nChannels = mChannels; 87 params.adtsUsed = 0; // We add adts header in the file writer if needed. 88 if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AAC_ENCPARAM, ¶ms)) { 89 ALOGE("Failed to set AAC encoder parameters"); 90 return UNKNOWN_ERROR; 91 } 92 93 return OK; 94 } 95 96 static status_t getSampleRateTableIndex(int32_t sampleRate, int32_t &index) { 97 static const int32_t kSampleRateTable[] = { 98 96000, 88200, 64000, 48000, 44100, 32000, 99 24000, 22050, 16000, 12000, 11025, 8000 100 }; 101 const int32_t tableSize = sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]); 102 for (int32_t i = 0; i < tableSize; ++i) { 103 if (sampleRate == kSampleRateTable[i]) { 104 index = i; 105 return OK; 106 } 107 } 108 109 ALOGE("Sampling rate %d bps is not supported", sampleRate); 110 return UNKNOWN_ERROR; 111 } 112 113 status_t AACEncoder::setAudioSpecificConfigData() { 114 ALOGV("setAudioSpecificConfigData: %d hz, %d bps, and %d channels", 115 mSampleRate, mBitRate, mChannels); 116 117 int32_t index = 0; 118 CHECK_EQ((status_t)OK, getSampleRateTableIndex(mSampleRate, index)); 119 if (mChannels > 2 || mChannels <= 0) { 120 ALOGE("Unsupported number of channels(%d)", mChannels); 121 return UNKNOWN_ERROR; 122 } 123 124 // OMX_AUDIO_AACObjectLC 125 mAudioSpecificConfigData[0] = ((0x02 << 3) | (index >> 1)); 126 mAudioSpecificConfigData[1] = ((index & 0x01) << 7) | (mChannels << 3); 127 return OK; 128 } 129 130 AACEncoder::~AACEncoder() { 131 if (mStarted) { 132 stop(); 133 } 134 } 135 136 status_t AACEncoder::start(MetaData *params) { 137 if (mStarted) { 138 ALOGW("Call start() when encoder already started"); 139 return OK; 140 } 141 142 mBufferGroup = new MediaBufferGroup; 143 mBufferGroup->add_buffer(new MediaBuffer(2048)); 144 145 CHECK_EQ((status_t)OK, initCheck()); 146 147 mNumInputSamples = 0; 148 mAnchorTimeUs = 0; 149 mFrameCount = 0; 150 151 mInputFrame = new int16_t[mChannels * kNumSamplesPerFrame]; 152 CHECK(mInputFrame != NULL); 153 154 status_t err = mSource->start(params); 155 if (err != OK) { 156 ALOGE("AudioSource is not available"); 157 return err; 158 } 159 160 mStarted = true; 161 162 return OK; 163 } 164 165 status_t AACEncoder::stop() { 166 if (mInputBuffer) { 167 mInputBuffer->release(); 168 mInputBuffer = NULL; 169 } 170 171 delete mBufferGroup; 172 mBufferGroup = NULL; 173 174 if (mInputFrame) { 175 delete[] mInputFrame; 176 mInputFrame = NULL; 177 } 178 179 if (!mStarted) { 180 ALOGW("Call stop() when encoder has not started"); 181 return ERROR_END_OF_STREAM; 182 } 183 184 mSource->stop(); 185 if (mEncoderHandle) { 186 CHECK_EQ((VO_U32)VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle)); 187 mEncoderHandle = NULL; 188 } 189 delete mApiHandle; 190 mApiHandle = NULL; 191 192 delete mMemOperator; 193 mMemOperator = NULL; 194 195 mStarted = false; 196 197 return OK; 198 } 199 200 sp<MetaData> AACEncoder::getFormat() { 201 sp<MetaData> srcFormat = mSource->getFormat(); 202 203 mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 204 205 int64_t durationUs; 206 if (srcFormat->findInt64(kKeyDuration, &durationUs)) { 207 mMeta->setInt64(kKeyDuration, durationUs); 208 } 209 210 mMeta->setCString(kKeyDecoderComponent, "AACEncoder"); 211 212 return mMeta; 213 } 214 215 status_t AACEncoder::read( 216 MediaBuffer **out, const ReadOptions *options) { 217 *out = NULL; 218 219 int64_t seekTimeUs; 220 ReadOptions::SeekMode mode; 221 CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode)); 222 223 MediaBuffer *buffer; 224 CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), (status_t)OK); 225 uint8_t *outPtr = (uint8_t *)buffer->data(); 226 bool readFromSource = false; 227 int64_t wallClockTimeUs = -1; 228 229 if (mFrameCount == 0) { 230 memcpy(outPtr, mAudioSpecificConfigData, 2); 231 buffer->set_range(0, 2); 232 buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 233 *out = buffer; 234 ++mFrameCount; 235 return OK; 236 } else if (mFrameCount == 1) { 237 buffer->meta_data()->setInt32(kKeyIsCodecConfig, false); 238 } 239 240 const int32_t nSamples = mChannels * kNumSamplesPerFrame; 241 while (mNumInputSamples < nSamples) { 242 if (mInputBuffer == NULL) { 243 if (mSource->read(&mInputBuffer, options) != OK) { 244 if (mNumInputSamples == 0) { 245 buffer->release(); 246 return ERROR_END_OF_STREAM; 247 } 248 memset(&mInputFrame[mNumInputSamples], 249 0, 250 sizeof(int16_t) * (nSamples - mNumInputSamples)); 251 mNumInputSamples = 0; 252 break; 253 } 254 255 size_t align = mInputBuffer->range_length() % sizeof(int16_t); 256 CHECK_EQ(align, (size_t)0); 257 258 int64_t timeUs; 259 if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) { 260 wallClockTimeUs = timeUs; 261 } 262 if (mInputBuffer->meta_data()->findInt64(kKeyAnchorTime, &timeUs)) { 263 mAnchorTimeUs = timeUs; 264 } 265 readFromSource = true; 266 } else { 267 readFromSource = false; 268 } 269 size_t copy = (nSamples - mNumInputSamples) * sizeof(int16_t); 270 271 if (copy > mInputBuffer->range_length()) { 272 copy = mInputBuffer->range_length(); 273 } 274 275 memcpy(&mInputFrame[mNumInputSamples], 276 (const uint8_t *) mInputBuffer->data() 277 + mInputBuffer->range_offset(), 278 copy); 279 280 mInputBuffer->set_range( 281 mInputBuffer->range_offset() + copy, 282 mInputBuffer->range_length() - copy); 283 284 if (mInputBuffer->range_length() == 0) { 285 mInputBuffer->release(); 286 mInputBuffer = NULL; 287 } 288 mNumInputSamples += copy / sizeof(int16_t); 289 if (mNumInputSamples >= nSamples) { 290 mNumInputSamples %= nSamples; 291 break; 292 } 293 } 294 295 VO_CODECBUFFER inputData; 296 memset(&inputData, 0, sizeof(inputData)); 297 inputData.Buffer = (unsigned char*) mInputFrame; 298 inputData.Length = nSamples * sizeof(int16_t); 299 CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData)); 300 301 VO_CODECBUFFER outputData; 302 memset(&outputData, 0, sizeof(outputData)); 303 VO_AUDIO_OUTPUTINFO outputInfo; 304 memset(&outputInfo, 0, sizeof(outputInfo)); 305 306 VO_U32 ret = VO_ERR_NONE; 307 size_t nOutputBytes = 0; 308 do { 309 outputData.Buffer = outPtr; 310 outputData.Length = buffer->size() - nOutputBytes; 311 ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo); 312 if (ret == VO_ERR_NONE) { 313 outPtr += outputData.Length; 314 nOutputBytes += outputData.Length; 315 } 316 } while (ret != VO_ERR_INPUT_BUFFER_SMALL); 317 buffer->set_range(0, nOutputBytes); 318 319 int64_t mediaTimeUs = 320 ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate; 321 322 buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs); 323 if (readFromSource && wallClockTimeUs != -1) { 324 buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs); 325 } 326 ++mFrameCount; 327 328 *out = buffer; 329 return OK; 330 } 331 332 } // namespace android 333