AACEncoder.cpp revision 29357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47
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),
398fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong      mInputFrame(NULL),
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mEncoderHandle(NULL),
41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mApiHandle(NULL),
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong      mMemOperator(NULL) {
43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::initCheck() {
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mApiHandle == NULL && mEncoderHandle == NULL);
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mMeta->findInt32(kKeyChannelCount, &mChannels));
498fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    CHECK(mChannels <= 2 && mChannels >= 1);
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mMeta->findInt32(kKeyBitRate, &mBitRate));
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mApiHandle = new VO_AUDIO_CODECAPI;
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mApiHandle);
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (VO_ERR_NONE != voGetAACEncAPI(mApiHandle)) {
5629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to get api handle");
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator = new VO_MEM_OPERATOR;
61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK(mMemOperator != NULL);
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Alloc = cmnMemAlloc;
63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Copy = cmnMemCopy;
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Free = cmnMemFree;
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Set = cmnMemSet;
66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMemOperator->Check = cmnMemCheck;
67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_CODEC_INIT_USERDATA userData;
69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&userData, 0, sizeof(userData));
70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    userData.memflag = VO_IMF_USERMEMOPERATOR;
71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    userData.memData = (VO_PTR) mMemOperator;
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (VO_ERR_NONE != mApiHandle->Init(&mEncoderHandle, VO_AUDIO_CodingAAC, &userData)) {
7329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to init AAC encoder");
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (OK != setAudioSpecificConfigData()) {
7729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to configure AAC encoder");
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    // Configure AAC encoder$
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    AACENC_PARAM params;
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&params, 0, sizeof(params));
84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    params.sampleRate = mSampleRate;
85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    params.bitRate = mBitRate;
86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    params.nChannels = mChannels;
87760943b5e7a09b602aba04ec451e97662f48b0a4James Dong    params.adtsUsed = 0;  // We add adts header in the file writer if needed.
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AAC_ENCPARAM,  &params)) {
8929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to set AAC encoder parameters");
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic status_t getSampleRateTableIndex(int32_t sampleRate, int32_t &index) {
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    static const int32_t kSampleRateTable[] = {
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        96000, 88200, 64000, 48000, 44100, 32000,
99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        24000, 22050, 16000, 12000, 11025, 8000
100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    };
101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    const int32_t tableSize = sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    for (int32_t i = 0; i < tableSize; ++i) {
103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (sampleRate == kSampleRateTable[i]) {
104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            index = i;
105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            return OK;
106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
10929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("Sampling rate %d bps is not supported", sampleRate);
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return UNKNOWN_ERROR;
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::setAudioSpecificConfigData() {
1143856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setAudioSpecificConfigData: %d hz, %d bps, and %d channels",
115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong         mSampleRate, mBitRate, mChannels);
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int32_t index;
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(OK, getSampleRateTableIndex(mSampleRate, index));
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mChannels > 2 || mChannels <= 0) {
12029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Unsupported number of channels(%d)", mChannels);
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return UNKNOWN_ERROR;
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    // OMX_AUDIO_AACObjectLC
125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mAudioSpecificConfigData[0] = ((0x02 << 3) | (index >> 1));
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mAudioSpecificConfigData[1] = ((index & 0x01) << 7) | (mChannels << 3);
127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongAACEncoder::~AACEncoder() {
131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mStarted) {
132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        stop();
133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::start(MetaData *params) {
137d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    if (mStarted) {
1385ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Call start() when encoder already started");
139d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong        return OK;
140d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong    }
141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup = new MediaBufferGroup;
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup->add_buffer(new MediaBuffer(2048));
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(OK, initCheck());
146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
147065d1aff96818df54456053f1574aec8a234d0deJames Dong    mNumInputSamples = 0;
148065d1aff96818df54456053f1574aec8a234d0deJames Dong    mAnchorTimeUs = 0;
149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mFrameCount = 0;
1508fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong
1518fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    mInputFrame = new int16_t[mChannels * kNumSamplesPerFrame];
1528fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    CHECK(mInputFrame != NULL);
1538fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong
154eaae38445a340c4857c1c5569475879a728e63b7James Dong    status_t err = mSource->start(params);
155eaae38445a340c4857c1c5569475879a728e63b7James Dong    if (err != OK) {
15629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block         ALOGE("AudioSource is not available");
157eaae38445a340c4857c1c5569475879a728e63b7James Dong        return err;
158eaae38445a340c4857c1c5569475879a728e63b7James Dong    }
159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mStarted = true;
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::stop() {
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mInputBuffer) {
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer->release();
168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mInputBuffer = NULL;
169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    delete mBufferGroup;
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mBufferGroup = NULL;
173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
174eaae38445a340c4857c1c5569475879a728e63b7James Dong    if (mInputFrame) {
175eaae38445a340c4857c1c5569475879a728e63b7James Dong        delete[] mInputFrame;
176eaae38445a340c4857c1c5569475879a728e63b7James Dong        mInputFrame = NULL;
177eaae38445a340c4857c1c5569475879a728e63b7James Dong    }
178eaae38445a340c4857c1c5569475879a728e63b7James Dong
179eaae38445a340c4857c1c5569475879a728e63b7James Dong    if (!mStarted) {
1805ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Call stop() when encoder has not started");
181eaae38445a340c4857c1c5569475879a728e63b7James Dong        return ERROR_END_OF_STREAM;
182eaae38445a340c4857c1c5569475879a728e63b7James Dong    }
183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
184eaae38445a340c4857c1c5569475879a728e63b7James Dong    mSource->stop();
185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mEncoderHandle) {
186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle));
187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mEncoderHandle = NULL;
188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    delete mApiHandle;
190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mApiHandle = NULL;
191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
19273870c96dc3d652b64b74b023f3df67edf7d08c0James Dong    delete mMemOperator;
19373870c96dc3d652b64b74b023f3df67edf7d08c0James Dong    mMemOperator = NULL;
19473870c96dc3d652b64b74b023f3df67edf7d08c0James Dong
195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mStarted = false;
196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongsp<MetaData> AACEncoder::getFormat() {
201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    sp<MetaData> srcFormat = mSource->getFormat();
202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t durationUs;
206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        mMeta->setInt64(kKeyDuration, durationUs);
208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    mMeta->setCString(kKeyDecoderComponent, "AACEncoder");
211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return mMeta;
213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::read(
216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        MediaBuffer **out, const ReadOptions *options) {
217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    status_t err;
218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = NULL;
220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    int64_t seekTimeUs;
222abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    ReadOptions::SeekMode mode;
223abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    MediaBuffer *buffer;
226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    uint8_t *outPtr = (uint8_t *)buffer->data();
228d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    bool readFromSource = false;
229caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong    int64_t wallClockTimeUs = -1;
230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    if (mFrameCount == 0) {
232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        memcpy(outPtr, mAudioSpecificConfigData, 2);
233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->set_range(0, 2);
234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, true);
235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        *out = buffer;
236a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong        ++mFrameCount;
237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        return OK;
238a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    } else if (mFrameCount == 1) {
239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        buffer->meta_data()->setInt32(kKeyIsCodecConfig, false);
240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
2428fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    const int32_t nSamples = mChannels * kNumSamplesPerFrame;
2438fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    while (mNumInputSamples < nSamples) {
244065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (mInputBuffer == NULL) {
245065d1aff96818df54456053f1574aec8a234d0deJames Dong            if (mSource->read(&mInputBuffer, options) != OK) {
246065d1aff96818df54456053f1574aec8a234d0deJames Dong                if (mNumInputSamples == 0) {
247542db5d438988360d491a5add1040a2df9aa90c9James Dong                    buffer->release();
248065d1aff96818df54456053f1574aec8a234d0deJames Dong                    return ERROR_END_OF_STREAM;
249065d1aff96818df54456053f1574aec8a234d0deJames Dong                }
250065d1aff96818df54456053f1574aec8a234d0deJames Dong                memset(&mInputFrame[mNumInputSamples],
251065d1aff96818df54456053f1574aec8a234d0deJames Dong                       0,
2528fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong                       sizeof(int16_t) * (nSamples - mNumInputSamples));
253065d1aff96818df54456053f1574aec8a234d0deJames Dong                mNumInputSamples = 0;
254065d1aff96818df54456053f1574aec8a234d0deJames Dong                break;
255065d1aff96818df54456053f1574aec8a234d0deJames Dong            }
256065d1aff96818df54456053f1574aec8a234d0deJames Dong
257065d1aff96818df54456053f1574aec8a234d0deJames Dong            size_t align = mInputBuffer->range_length() % sizeof(int16_t);
258065d1aff96818df54456053f1574aec8a234d0deJames Dong            CHECK_EQ(align, 0);
259065d1aff96818df54456053f1574aec8a234d0deJames Dong
260065d1aff96818df54456053f1574aec8a234d0deJames Dong            int64_t timeUs;
261caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong            if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) {
262caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong                wallClockTimeUs = timeUs;
263caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong            }
2643c3763d2ee1cd1fba7fe522fbaf0faca315d8c2aJames Dong            if (mInputBuffer->meta_data()->findInt64(kKeyAnchorTime, &timeUs)) {
265065d1aff96818df54456053f1574aec8a234d0deJames Dong                mAnchorTimeUs = timeUs;
266065d1aff96818df54456053f1574aec8a234d0deJames Dong            }
267d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong            readFromSource = true;
268d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong        } else {
269d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong            readFromSource = false;
270065d1aff96818df54456053f1574aec8a234d0deJames Dong        }
2718fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong        size_t copy = (nSamples - mNumInputSamples) * sizeof(int16_t);
272065d1aff96818df54456053f1574aec8a234d0deJames Dong
273065d1aff96818df54456053f1574aec8a234d0deJames Dong        if (copy > mInputBuffer->range_length()) {
274065d1aff96818df54456053f1574aec8a234d0deJames Dong            copy = mInputBuffer->range_length();
275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
276065d1aff96818df54456053f1574aec8a234d0deJames Dong
277065d1aff96818df54456053f1574aec8a234d0deJames Dong        memcpy(&mInputFrame[mNumInputSamples],
278065d1aff96818df54456053f1574aec8a234d0deJames Dong               (const uint8_t *) mInputBuffer->data()
279065d1aff96818df54456053f1574aec8a234d0deJames Dong                    + mInputBuffer->range_offset(),
280065d1aff96818df54456053f1574aec8a234d0deJames Dong               copy);
281065d1aff96818df54456053f1574aec8a234d0deJames Dong
282065d1aff96818df54456053f1574aec8a234d0deJames Dong        mInputBuffer->set_range(
283065d1aff96818df54456053f1574aec8a234d0deJames Dong               mInputBuffer->range_offset() + copy,
284065d1aff96818df54456053f1574aec8a234d0deJames Dong               mInputBuffer->range_length() - copy);
285065d1aff96818df54456053f1574aec8a234d0deJames Dong
286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        if (mInputBuffer->range_length() == 0) {
287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer->release();
288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong            mInputBuffer = NULL;
289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong        }
290065d1aff96818df54456053f1574aec8a234d0deJames Dong        mNumInputSamples += copy / sizeof(int16_t);
2918fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong        if (mNumInputSamples >= nSamples) {
2928fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong            mNumInputSamples %= nSamples;
293065d1aff96818df54456053f1574aec8a234d0deJames Dong            break;
294065d1aff96818df54456053f1574aec8a234d0deJames Dong        }
295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    }
296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
297065d1aff96818df54456053f1574aec8a234d0deJames Dong    VO_CODECBUFFER inputData;
298065d1aff96818df54456053f1574aec8a234d0deJames Dong    memset(&inputData, 0, sizeof(inputData));
299065d1aff96818df54456053f1574aec8a234d0deJames Dong    inputData.Buffer = (unsigned char*) mInputFrame;
3008fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    inputData.Length = nSamples * sizeof(int16_t);
301065d1aff96818df54456053f1574aec8a234d0deJames Dong    CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData));
302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_CODECBUFFER outputData;
304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputData, 0, sizeof(outputData));
305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_AUDIO_OUTPUTINFO outputInfo;
306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    memset(&outputInfo, 0, sizeof(outputInfo));
307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    VO_U32 ret = VO_ERR_NONE;
3098fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    size_t nOutputBytes = 0;
3108fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    do {
3118fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong        outputData.Buffer = outPtr;
3128fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong        outputData.Length = buffer->size() - nOutputBytes;
3138fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong        ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo);
3148fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong        if (ret == VO_ERR_NONE) {
3158fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong            outPtr += outputData.Length;
3168fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong            nOutputBytes += outputData.Length;
3178fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong        }
3188fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    } while (ret != VO_ERR_INPUT_BUFFER_SMALL);
3198fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong    buffer->set_range(0, nOutputBytes);
320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
321d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    int64_t mediaTimeUs =
322d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong        ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate;
3238fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong
324d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs);
325caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong    if (readFromSource && wallClockTimeUs != -1) {
326d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong        buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs);
327d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong    }
328a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong    ++mFrameCount;
329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    *out = buffer;
331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong    return OK;
332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}  // namespace android
335