OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / media / libstagefright / codecs / aacenc / AACEncoder.cpp
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
31 namespace android {
32
33 AACEncoder::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
44 status_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(&params, 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,  &params)) {
87         LOGE("Failed to set AAC encoder parameters");
88         return UNKNOWN_ERROR;
89     }
90
91     return OK;
92 }
93
94 static 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
111 status_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
128 AACEncoder::~AACEncoder() {
129     if (mStarted) {
130         stop();
131     }
132 }
133
134 status_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
155 status_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
183 sp<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
198 status_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(kKeyAnchorTime, &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