AACEncoder.cpp revision 956c553ab0ce72f8074ad0fda2ffd66a0305700c
1956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*
2956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * Copyright (C) 2010 The Android Open Source Project
3956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *
4956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * Licensed under the Apache License, Version 2.0 (the "License");
5956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * you may not use this file except in compliance with the License.
6956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * You may obtain a copy of the License at
7956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *
8956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *      http://www.apache.org/licenses/LICENSE-2.0
9956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *
10956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * Unless required by applicable law or agreed to in writing, software
11956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * distributed under the License is distributed on an "AS IS" BASIS,
12956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * See the License for the specific language governing permissions and
14956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong * limitations under the License.
15956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */
16956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
17956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong//#define LOG_NDEBUG 0
18956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define LOG_TAG "AACEncoder"
19956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include <utils/Log.h>
20956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "AACEncoder.h"
22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "voAAC.h"
23956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "cmnMemory.h"
24956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include <media/stagefright/MediaBufferGroup.h>
26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include <media/stagefright/MediaDebug.h>
27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include <media/stagefright/MediaDefs.h>
28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include <media/stagefright/MediaErrors.h>
29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include <media/stagefright/MetaData.h>
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongnamespace android {
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongAACEncoder::AACEncoder(const sp<MediaSource> &source, const sp<MetaData> &meta)
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    : mSource(source),
35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mMeta(meta),
36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mStarted(false),
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mBufferGroup(NULL),
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mInputBuffer(NULL),
39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mEncoderHandle(NULL),
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mApiHandle(NULL),
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mMemOperator(NULL) {
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::initCheck() {
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mApiHandle == NULL && mEncoderHandle == NULL);
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mMeta->findInt32(kKeyChannelCount, &mChannels));
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mMeta->findInt32(kKeyBitRate, &mBitRate));
49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mApiHandle = new VO_AUDIO_CODECAPI;
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mApiHandle);
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (VO_ERR_NONE != voGetAACEncAPI(mApiHandle)) {
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        LOGE("Failed to get api handle");
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator = new VO_MEM_OPERATOR;
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mMemOperator != NULL);
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Alloc = cmnMemAlloc;
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Copy = cmnMemCopy;
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Free = cmnMemFree;
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Set = cmnMemSet;
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Check = cmnMemCheck;
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_CODEC_INIT_USERDATA userData;
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&userData, 0, sizeof(userData));
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    userData.memflag = VO_IMF_USERMEMOPERATOR;
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    userData.memData = (VO_PTR) mMemOperator;
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (VO_ERR_NONE != mApiHandle->Init(&mEncoderHandle, VO_AUDIO_CodingAAC, &userData)) {
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        LOGE("Failed to init AAC encoder");
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (OK != setAudioSpecificConfigData()) {
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        LOGE("Failed to configure AAC encoder");
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    // Configure AAC encoder$
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    AACENC_PARAM params;
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&params, 0, sizeof(params));
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    params.sampleRate = mSampleRate;
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    params.bitRate = mBitRate;
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    params.nChannels = mChannels;
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    params.adtsUsed = 0;  // For MP4 file, don't use adts format$
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AAC_ENCPARAM,  &params)) {
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        LOGE("Failed to set AAC encoder parameters");
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic status_t getSampleRateTableIndex(int32_t sampleRate, int32_t &index) {
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    static const int32_t kSampleRateTable[] = {
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        96000, 88200, 64000, 48000, 44100, 32000,
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        24000, 22050, 16000, 12000, 11025, 8000
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    };
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    const int32_t tableSize = sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);
100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for (int32_t i = 0; i < tableSize; ++i) {
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (sampleRate == kSampleRateTable[i]) {
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            index = i;
103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            return OK;
104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    LOGE("Sampling rate %d bps is not supported", sampleRate);
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return UNKNOWN_ERROR;
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::setAudioSpecificConfigData() {
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    LOGV("setAudioSpecificConfigData: %d hz, %d bps, and %d channels",
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong         mSampleRate, mBitRate, mChannels);
114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int32_t index;
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(OK, getSampleRateTableIndex(mSampleRate, index));
117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mChannels > 2 || mChannels <= 0) {
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        LOGE("Unsupported number of channels(%d)", mChannels);
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    // OMX_AUDIO_AACObjectLC
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mAudioSpecificConfigData[0] = ((0x02 << 3) | (index >> 1));
124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mAudioSpecificConfigData[1] = ((index & 0x01) << 7) | (mChannels << 3);
125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongAACEncoder::~AACEncoder() {
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mStarted) {
130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        stop();
131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::start(MetaData *params) {
135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(!mStarted);
136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup = new MediaBufferGroup;
138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup->add_buffer(new MediaBuffer(2048));
139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(OK, initCheck());
141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mFrameCount = 0;
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mSource->start();
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mStarted = true;
146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::stop() {
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mStarted);
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mInputBuffer) {
154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer->release();
155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer = NULL;
156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    delete mBufferGroup;
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup = NULL;
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mSource->stop();
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mEncoderHandle) {
164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mEncoderHandle = NULL;
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    delete mApiHandle;
168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mApiHandle = NULL;
169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mStarted = false;
171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongsp<MetaData> AACEncoder::getFormat() {
176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    sp<MetaData> srcFormat = mSource->getFormat();
177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t durationUs;
181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mMeta->setInt64(kKeyDuration, durationUs);
183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMeta->setCString(kKeyDecoderComponent, "AACEncoder");
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return mMeta;
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::read(
191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        MediaBuffer **out, const ReadOptions *options) {
192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    status_t err;
193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = NULL;
195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t seekTimeUs;
197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs));
198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    MediaBuffer *buffer;
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    uint8_t *outPtr = (uint8_t *)buffer->data();
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mFrameCount == 0) {
204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        memcpy(outPtr, mAudioSpecificConfigData, 2);
205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->set_range(0, 2);
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        *out = buffer;
208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        ++mFrameCount;
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer = NULL;
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return OK;
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    } else {
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, false);
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mInputBuffer == NULL) {
216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (mSource->read(&mInputBuffer, options) != OK) {
217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            LOGE("failed to read from input audio source");
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            return UNKNOWN_ERROR;
219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (mInputBuffer->range_length() == 0) {
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer->release();
222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer = NULL;
223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            return ERROR_END_OF_STREAM;
224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        VO_CODECBUFFER inputData;
226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        memset(&inputData, 0, sizeof(inputData));
227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        inputData.Buffer = (unsigned char*) mInputBuffer->data();
228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        inputData.Length = mInputBuffer->range_length();
229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData));
230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mInputBuffer != NULL);
233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_CODECBUFFER outputData;
235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputData, 0, sizeof(outputData));
236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_AUDIO_OUTPUTINFO outputInfo;
237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputInfo, 0, sizeof(outputInfo));
238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_U32 ret = VO_ERR_NONE;
240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int32_t outputLength = 0;
241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    outputData.Buffer = outPtr;
242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    outputData.Length = buffer->size();
243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo);
244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL) {
245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        outputLength += outputData.Length;
246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (ret == VO_ERR_INPUT_BUFFER_SMALL) {  // All done
247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer->release();
248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer = NULL;
249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    } else {
251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        LOGE("failed to encode the input data 0x%lx", ret);
252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    buffer->set_range(0, outputLength);
255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    ++mFrameCount;
256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t timestampUs = (mFrameCount * 1000000LL * 1024) / mSampleRate;
257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    buffer->meta_data()->setInt64(kKeyTime, timestampUs);
259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = buffer;
261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}  // namespace android
265