AACEncoder.cpp revision 065d1aff96818df54456053f1574aec8a234d0de
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
142065d1aff96818df54456053f1574aec8a234d0deJames Dong    mNumInputSamples = 0;
143065d1aff96818df54456053f1574aec8a234d0deJames Dong    mAnchorTimeUs = 0;
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mFrameCount = 0;
145f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    mSource->start(params);
146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mStarted = true;
148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::stop() {
153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mStarted);
154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mInputBuffer) {
156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer->release();
157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer = NULL;
158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    delete mBufferGroup;
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup = NULL;
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mSource->stop();
164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mEncoderHandle) {
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mEncoderHandle = NULL;
168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    delete mApiHandle;
170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mApiHandle = NULL;
171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mStarted = false;
173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongsp<MetaData> AACEncoder::getFormat() {
178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    sp<MetaData> srcFormat = mSource->getFormat();
179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t durationUs;
183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mMeta->setInt64(kKeyDuration, durationUs);
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMeta->setCString(kKeyDecoderComponent, "AACEncoder");
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return mMeta;
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::read(
193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        MediaBuffer **out, const ReadOptions *options) {
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    status_t err;
195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = NULL;
197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t seekTimeUs;
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs));
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    MediaBuffer *buffer;
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    uint8_t *outPtr = (uint8_t *)buffer->data();
204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mFrameCount == 0) {
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        memcpy(outPtr, mAudioSpecificConfigData, 2);
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->set_range(0, 2);
208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        *out = buffer;
210a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong        ++mFrameCount;
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return OK;
212a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    } else if (mFrameCount == 1) {
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, false);
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
216065d1aff96818df54456053f1574aec8a234d0deJames Dong    while (mNumInputSamples < kNumSamplesPerFrame) {
217065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (mInputBuffer == NULL) {
218065d1aff96818df54456053f1574aec8a234d0deJames Dong            if (mSource->read(&mInputBuffer, options) != OK) {
219065d1aff96818df54456053f1574aec8a234d0deJames Dong                if (mNumInputSamples == 0) {
220065d1aff96818df54456053f1574aec8a234d0deJames Dong                    return ERROR_END_OF_STREAM;
221065d1aff96818df54456053f1574aec8a234d0deJames Dong                }
222065d1aff96818df54456053f1574aec8a234d0deJames Dong                memset(&mInputFrame[mNumInputSamples],
223065d1aff96818df54456053f1574aec8a234d0deJames Dong                       0,
224065d1aff96818df54456053f1574aec8a234d0deJames Dong                       sizeof(int16_t) * (kNumSamplesPerFrame - mNumInputSamples));
225065d1aff96818df54456053f1574aec8a234d0deJames Dong                mNumInputSamples = 0;
226065d1aff96818df54456053f1574aec8a234d0deJames Dong                break;
227065d1aff96818df54456053f1574aec8a234d0deJames Dong            }
228065d1aff96818df54456053f1574aec8a234d0deJames Dong
229065d1aff96818df54456053f1574aec8a234d0deJames Dong            size_t align = mInputBuffer->range_length() % sizeof(int16_t);
230065d1aff96818df54456053f1574aec8a234d0deJames Dong            CHECK_EQ(align, 0);
231065d1aff96818df54456053f1574aec8a234d0deJames Dong
232065d1aff96818df54456053f1574aec8a234d0deJames Dong            int64_t timeUs;
233065d1aff96818df54456053f1574aec8a234d0deJames Dong            if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
234065d1aff96818df54456053f1574aec8a234d0deJames Dong                mAnchorTimeUs = timeUs;
235065d1aff96818df54456053f1574aec8a234d0deJames Dong            }
236065d1aff96818df54456053f1574aec8a234d0deJames Dong        }
237065d1aff96818df54456053f1574aec8a234d0deJames Dong        size_t copy =
238065d1aff96818df54456053f1574aec8a234d0deJames Dong            (kNumSamplesPerFrame - mNumInputSamples) * sizeof(int16_t);
239065d1aff96818df54456053f1574aec8a234d0deJames Dong
240065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (copy > mInputBuffer->range_length()) {
241065d1aff96818df54456053f1574aec8a234d0deJames Dong            copy = mInputBuffer->range_length();
242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
243065d1aff96818df54456053f1574aec8a234d0deJames Dong
244065d1aff96818df54456053f1574aec8a234d0deJames Dong        memcpy(&mInputFrame[mNumInputSamples],
245065d1aff96818df54456053f1574aec8a234d0deJames Dong               (const uint8_t *) mInputBuffer->data()
246065d1aff96818df54456053f1574aec8a234d0deJames Dong                    + mInputBuffer->range_offset(),
247065d1aff96818df54456053f1574aec8a234d0deJames Dong               copy);
248065d1aff96818df54456053f1574aec8a234d0deJames Dong
249065d1aff96818df54456053f1574aec8a234d0deJames Dong        mInputBuffer->set_range(
250065d1aff96818df54456053f1574aec8a234d0deJames Dong               mInputBuffer->range_offset() + copy,
251065d1aff96818df54456053f1574aec8a234d0deJames Dong               mInputBuffer->range_length() - copy);
252065d1aff96818df54456053f1574aec8a234d0deJames Dong
253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (mInputBuffer->range_length() == 0) {
254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer->release();
255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer = NULL;
256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
257065d1aff96818df54456053f1574aec8a234d0deJames Dong        mNumInputSamples += copy / sizeof(int16_t);
258065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (mNumInputSamples >= kNumSamplesPerFrame) {
259065d1aff96818df54456053f1574aec8a234d0deJames Dong            mNumInputSamples %= kNumSamplesPerFrame;
260065d1aff96818df54456053f1574aec8a234d0deJames Dong            break;
261065d1aff96818df54456053f1574aec8a234d0deJames Dong        }
262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
264065d1aff96818df54456053f1574aec8a234d0deJames Dong    VO_CODECBUFFER inputData;
265065d1aff96818df54456053f1574aec8a234d0deJames Dong    memset(&inputData, 0, sizeof(inputData));
266065d1aff96818df54456053f1574aec8a234d0deJames Dong    inputData.Buffer = (unsigned char*) mInputFrame;
267065d1aff96818df54456053f1574aec8a234d0deJames Dong    inputData.Length = kNumSamplesPerFrame * sizeof(int16_t);
268065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData));
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_CODECBUFFER outputData;
271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputData, 0, sizeof(outputData));
272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_AUDIO_OUTPUTINFO outputInfo;
273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputInfo, 0, sizeof(outputInfo));
274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_U32 ret = VO_ERR_NONE;
276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    outputData.Buffer = outPtr;
277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    outputData.Length = buffer->size();
278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo);
279065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL);
280065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(outputData.Length != 0);
281065d1aff96818df54456053f1574aec8a234d0deJames Dong    buffer->set_range(0, outputData.Length);
282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
283065d1aff96818df54456053f1574aec8a234d0deJames Dong    int64_t timestampUs = ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;
284a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    ++mFrameCount;
285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    buffer->meta_data()->setInt64(kKeyTime, timestampUs);
286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = buffer;
288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}  // namespace android
292