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(¶ms, 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, ¶ms)) { 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