AACEncoder.cpp revision d707fcb3e29707ca4a5935c294ef0b38eb5aba5f
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();
211d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    bool readFromSource = false;
212d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    int64_t wallClockTimeUs = 0;
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mFrameCount == 0) {
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        memcpy(outPtr, mAudioSpecificConfigData, 2);
216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->set_range(0, 2);
217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        *out = buffer;
219a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong        ++mFrameCount;
220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return OK;
221a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    } else if (mFrameCount == 1) {
222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, false);
223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
225065d1aff96818df54456053f1574aec8a234d0deJames Dong    while (mNumInputSamples < kNumSamplesPerFrame) {
226065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (mInputBuffer == NULL) {
227065d1aff96818df54456053f1574aec8a234d0deJames Dong            if (mSource->read(&mInputBuffer, options) != OK) {
228065d1aff96818df54456053f1574aec8a234d0deJames Dong                if (mNumInputSamples == 0) {
229542db5d438988360d491a5add1040a2df9aa90c9James Dong                    buffer->release();
230065d1aff96818df54456053f1574aec8a234d0deJames Dong                    return ERROR_END_OF_STREAM;
231065d1aff96818df54456053f1574aec8a234d0deJames Dong                }
232065d1aff96818df54456053f1574aec8a234d0deJames Dong                memset(&mInputFrame[mNumInputSamples],
233065d1aff96818df54456053f1574aec8a234d0deJames Dong                       0,
234065d1aff96818df54456053f1574aec8a234d0deJames Dong                       sizeof(int16_t) * (kNumSamplesPerFrame - mNumInputSamples));
235065d1aff96818df54456053f1574aec8a234d0deJames Dong                mNumInputSamples = 0;
236065d1aff96818df54456053f1574aec8a234d0deJames Dong                break;
237065d1aff96818df54456053f1574aec8a234d0deJames Dong            }
238065d1aff96818df54456053f1574aec8a234d0deJames Dong
239065d1aff96818df54456053f1574aec8a234d0deJames Dong            size_t align = mInputBuffer->range_length() % sizeof(int16_t);
240065d1aff96818df54456053f1574aec8a234d0deJames Dong            CHECK_EQ(align, 0);
241065d1aff96818df54456053f1574aec8a234d0deJames Dong
242065d1aff96818df54456053f1574aec8a234d0deJames Dong            int64_t timeUs;
243d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong            CHECK(mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs));
244d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong            wallClockTimeUs = timeUs;
245065d1aff96818df54456053f1574aec8a234d0deJames Dong            if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
246065d1aff96818df54456053f1574aec8a234d0deJames Dong                mAnchorTimeUs = timeUs;
247065d1aff96818df54456053f1574aec8a234d0deJames Dong            }
248d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong            readFromSource = true;
249d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong        } else {
250d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong            readFromSource = false;
251065d1aff96818df54456053f1574aec8a234d0deJames Dong        }
252065d1aff96818df54456053f1574aec8a234d0deJames Dong        size_t copy =
253065d1aff96818df54456053f1574aec8a234d0deJames Dong            (kNumSamplesPerFrame - mNumInputSamples) * sizeof(int16_t);
254065d1aff96818df54456053f1574aec8a234d0deJames Dong
255065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (copy > mInputBuffer->range_length()) {
256065d1aff96818df54456053f1574aec8a234d0deJames Dong            copy = mInputBuffer->range_length();
257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
258065d1aff96818df54456053f1574aec8a234d0deJames Dong
259065d1aff96818df54456053f1574aec8a234d0deJames Dong        memcpy(&mInputFrame[mNumInputSamples],
260065d1aff96818df54456053f1574aec8a234d0deJames Dong               (const uint8_t *) mInputBuffer->data()
261065d1aff96818df54456053f1574aec8a234d0deJames Dong                    + mInputBuffer->range_offset(),
262065d1aff96818df54456053f1574aec8a234d0deJames Dong               copy);
263065d1aff96818df54456053f1574aec8a234d0deJames Dong
264065d1aff96818df54456053f1574aec8a234d0deJames Dong        mInputBuffer->set_range(
265065d1aff96818df54456053f1574aec8a234d0deJames Dong               mInputBuffer->range_offset() + copy,
266065d1aff96818df54456053f1574aec8a234d0deJames Dong               mInputBuffer->range_length() - copy);
267065d1aff96818df54456053f1574aec8a234d0deJames Dong
268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (mInputBuffer->range_length() == 0) {
269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer->release();
270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer = NULL;
271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
272065d1aff96818df54456053f1574aec8a234d0deJames Dong        mNumInputSamples += copy / sizeof(int16_t);
273065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (mNumInputSamples >= kNumSamplesPerFrame) {
274065d1aff96818df54456053f1574aec8a234d0deJames Dong            mNumInputSamples %= kNumSamplesPerFrame;
275065d1aff96818df54456053f1574aec8a234d0deJames Dong            break;
276065d1aff96818df54456053f1574aec8a234d0deJames Dong        }
277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
279065d1aff96818df54456053f1574aec8a234d0deJames Dong    VO_CODECBUFFER inputData;
280065d1aff96818df54456053f1574aec8a234d0deJames Dong    memset(&inputData, 0, sizeof(inputData));
281065d1aff96818df54456053f1574aec8a234d0deJames Dong    inputData.Buffer = (unsigned char*) mInputFrame;
282065d1aff96818df54456053f1574aec8a234d0deJames Dong    inputData.Length = kNumSamplesPerFrame * sizeof(int16_t);
283065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData));
284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_CODECBUFFER outputData;
286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputData, 0, sizeof(outputData));
287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_AUDIO_OUTPUTINFO outputInfo;
288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputInfo, 0, sizeof(outputInfo));
289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_U32 ret = VO_ERR_NONE;
291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    outputData.Buffer = outPtr;
292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    outputData.Length = buffer->size();
293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo);
294065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(ret == VO_ERR_NONE || ret == VO_ERR_INPUT_BUFFER_SMALL);
295065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(outputData.Length != 0);
296065d1aff96818df54456053f1574aec8a234d0deJames Dong    buffer->set_range(0, outputData.Length);
297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
298d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    int64_t mediaTimeUs =
299d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong        ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;
300d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs);
301d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    if (readFromSource) {
302d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong        buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs);
303d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    }
304a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    ++mFrameCount;
305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = buffer;
307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}  // namespace android
311