AACEncoder.cpp revision abd1f4f870925d6776dbe4b930b759a1ab6595ca
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) {
135d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (mStarted) {
136d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        LOGW("Call start() when encoder already started");
137d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return OK;
138d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup = new MediaBufferGroup;
141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup->add_buffer(new MediaBuffer(2048));
142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(OK, initCheck());
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
145065d1aff96818df54456053f1574aec8a234d0deJames Dong    mNumInputSamples = 0;
146065d1aff96818df54456053f1574aec8a234d0deJames Dong    mAnchorTimeUs = 0;
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mFrameCount = 0;
148f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong    mSource->start(params);
149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mStarted = true;
151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::stop() {
156d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (!mStarted) {
157d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        LOGW("Call stop() when encoder has not started");
158d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return OK;
159d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mInputBuffer) {
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer->release();
163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer = NULL;
164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    delete mBufferGroup;
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup = NULL;
168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mSource->stop();
170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mEncoderHandle) {
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mEncoderHandle = NULL;
174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    delete mApiHandle;
176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mApiHandle = NULL;
177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mStarted = false;
179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongsp<MetaData> AACEncoder::getFormat() {
184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    sp<MetaData> srcFormat = mSource->getFormat();
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t durationUs;
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mMeta->setInt64(kKeyDuration, durationUs);
191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMeta->setCString(kKeyDecoderComponent, "AACEncoder");
194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return mMeta;
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::read(
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        MediaBuffer **out, const ReadOptions *options) {
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    status_t err;
201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = NULL;
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t seekTimeUs;
205abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
206abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    MediaBuffer *buffer;
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    uint8_t *outPtr = (uint8_t *)buffer->data();
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mFrameCount == 0) {
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        memcpy(outPtr, mAudioSpecificConfigData, 2);
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->set_range(0, 2);
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        *out = buffer;
217a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong        ++mFrameCount;
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return OK;
219a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    } else if (mFrameCount == 1) {
220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, false);
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
223065d1aff96818df54456053f1574aec8a234d0deJames Dong    while (mNumInputSamples < kNumSamplesPerFrame) {
224065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (mInputBuffer == NULL) {
225065d1aff96818df54456053f1574aec8a234d0deJames Dong            if (mSource->read(&mInputBuffer, options) != OK) {
226065d1aff96818df54456053f1574aec8a234d0deJames Dong                if (mNumInputSamples == 0) {
227065d1aff96818df54456053f1574aec8a234d0deJames Dong                    return ERROR_END_OF_STREAM;
228065d1aff96818df54456053f1574aec8a234d0deJames Dong                }
229065d1aff96818df54456053f1574aec8a234d0deJames Dong                memset(&mInputFrame[mNumInputSamples],
230065d1aff96818df54456053f1574aec8a234d0deJames Dong                       0,
231065d1aff96818df54456053f1574aec8a234d0deJames Dong                       sizeof(int16_t) * (kNumSamplesPerFrame - mNumInputSamples));
232065d1aff96818df54456053f1574aec8a234d0deJames Dong                mNumInputSamples = 0;
233065d1aff96818df54456053f1574aec8a234d0deJames Dong                break;
234065d1aff96818df54456053f1574aec8a234d0deJames Dong            }
235065d1aff96818df54456053f1574aec8a234d0deJames Dong
236065d1aff96818df54456053f1574aec8a234d0deJames Dong            size_t align = mInputBuffer->range_length() % sizeof(int16_t);
237065d1aff96818df54456053f1574aec8a234d0deJames Dong            CHECK_EQ(align, 0);
238065d1aff96818df54456053f1574aec8a234d0deJames Dong
239065d1aff96818df54456053f1574aec8a234d0deJames Dong            int64_t timeUs;
240065d1aff96818df54456053f1574aec8a234d0deJames Dong            if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
241065d1aff96818df54456053f1574aec8a234d0deJames Dong                mAnchorTimeUs = timeUs;
242065d1aff96818df54456053f1574aec8a234d0deJames Dong            }
243065d1aff96818df54456053f1574aec8a234d0deJames Dong        }
244065d1aff96818df54456053f1574aec8a234d0deJames Dong        size_t copy =
245065d1aff96818df54456053f1574aec8a234d0deJames Dong            (kNumSamplesPerFrame - mNumInputSamples) * sizeof(int16_t);
246065d1aff96818df54456053f1574aec8a234d0deJames Dong
247065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (copy > mInputBuffer->range_length()) {
248065d1aff96818df54456053f1574aec8a234d0deJames Dong            copy = mInputBuffer->range_length();
249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
250065d1aff96818df54456053f1574aec8a234d0deJames Dong
251065d1aff96818df54456053f1574aec8a234d0deJames Dong        memcpy(&mInputFrame[mNumInputSamples],
252065d1aff96818df54456053f1574aec8a234d0deJames Dong               (const uint8_t *) mInputBuffer->data()
253065d1aff96818df54456053f1574aec8a234d0deJames Dong                    + mInputBuffer->range_offset(),
254065d1aff96818df54456053f1574aec8a234d0deJames Dong               copy);
255065d1aff96818df54456053f1574aec8a234d0deJames Dong
256065d1aff96818df54456053f1574aec8a234d0deJames Dong        mInputBuffer->set_range(
257065d1aff96818df54456053f1574aec8a234d0deJames Dong               mInputBuffer->range_offset() + copy,
258065d1aff96818df54456053f1574aec8a234d0deJames Dong               mInputBuffer->range_length() - copy);
259065d1aff96818df54456053f1574aec8a234d0deJames Dong
260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (mInputBuffer->range_length() == 0) {
261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer->release();
262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer = NULL;
263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
264065d1aff96818df54456053f1574aec8a234d0deJames Dong        mNumInputSamples += copy / sizeof(int16_t);
265065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (mNumInputSamples >= kNumSamplesPerFrame) {
266065d1aff96818df54456053f1574aec8a234d0deJames Dong            mNumInputSamples %= kNumSamplesPerFrame;
267065d1aff96818df54456053f1574aec8a234d0deJames Dong            break;
268065d1aff96818df54456053f1574aec8a234d0deJames Dong        }
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
271065d1aff96818df54456053f1574aec8a234d0deJames Dong    VO_CODECBUFFER inputData;
272065d1aff96818df54456053f1574aec8a234d0deJames Dong    memset(&inputData, 0, sizeof(inputData));
273065d1aff96818df54456053f1574aec8a234d0deJames Dong    inputData.Buffer = (unsigned char*) mInputFrame;
274065d1aff96818df54456053f1574aec8a234d0deJames Dong    inputData.Length = kNumSamplesPerFrame * sizeof(int16_t);
275065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData));
276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_CODECBUFFER outputData;
278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputData, 0, sizeof(outputData));
279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_AUDIO_OUTPUTINFO outputInfo;
280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputInfo, 0, sizeof(outputInfo));
281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_U32 ret = VO_ERR_NONE;
283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    outputData.Buffer = outPtr;
284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    outputData.Length = buffer->size();
285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo);
286065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL);
287065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(outputData.Length != 0);
288065d1aff96818df54456053f1574aec8a234d0deJames Dong    buffer->set_range(0, outputData.Length);
289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
290065d1aff96818df54456053f1574aec8a234d0deJames Dong    int64_t timestampUs = ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;
291a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    ++mFrameCount;
292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    buffer->meta_data()->setInt64(kKeyTime, timestampUs);
293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = buffer;
295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}  // namespace android
299