AACEncoder.cpp revision 8fff6bb0000e43f02c9d04ca90f941fdefdc1356
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)) { 56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong LOGE("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)) { 73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong LOGE("Failed to init AAC encoder"); 74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return UNKNOWN_ERROR; 75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (OK != setAudioSpecificConfigData()) { 77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong LOGE("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(¶ms, 0, sizeof(params)); 84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong params.sampleRate = mSampleRate; 85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong params.bitRate = mBitRate; 86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong params.nChannels = mChannels; 87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong params.adtsUsed = 0; // For MP4 file, don't use adts format$ 88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (VO_ERR_NONE != mApiHandle->SetParam(mEncoderHandle, VO_PID_AAC_ENCPARAM, ¶ms)) { 89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong LOGE("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 109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong LOGE("Sampling rate %d bps is not supported", sampleRate); 110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return UNKNOWN_ERROR; 111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::setAudioSpecificConfigData() { 114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong LOGV("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) { 120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong LOGE("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) { 138d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong LOGW("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 154f60cafe0e6aad8f9ce54660fa88b651ae4e749e6James Dong mSource->start(params); 155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mStarted = true; 157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return OK; 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::stop() { 162d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong if (!mStarted) { 163d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong LOGW("Call stop() when encoder has not started"); 164d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong return OK; 165d329e21495eda9dbc531fdd0c26c77f1593ac3f4James Dong } 166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mInputBuffer) { 168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mInputBuffer->release(); 169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mInputBuffer = NULL; 170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong delete mBufferGroup; 173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mBufferGroup = NULL; 174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mSource->stop(); 176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mEncoderHandle) { 178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CHECK_EQ(VO_ERR_NONE, mApiHandle->Uninit(mEncoderHandle)); 179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mEncoderHandle = NULL; 180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong delete mApiHandle; 182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mApiHandle = NULL; 183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mStarted = false; 1858fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong if (mInputFrame) { 1868fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong delete[] mInputFrame; 1878fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong mInputFrame = NULL; 1888fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong } 189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return OK; 191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongsp<MetaData> AACEncoder::getFormat() { 194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sp<MetaData> srcFormat = mSource->getFormat(); 195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC); 197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong int64_t durationUs; 199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (srcFormat->findInt64(kKeyDuration, &durationUs)) { 200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mMeta->setInt64(kKeyDuration, durationUs); 201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mMeta->setCString(kKeyDecoderComponent, "AACEncoder"); 204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return mMeta; 206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatus_t AACEncoder::read( 209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong MediaBuffer **out, const ReadOptions *options) { 210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong status_t err; 211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *out = NULL; 213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong int64_t seekTimeUs; 215abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber ReadOptions::SeekMode mode; 216abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode)); 217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong MediaBuffer *buffer; 219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK); 220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong uint8_t *outPtr = (uint8_t *)buffer->data(); 221d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong bool readFromSource = false; 222caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong int64_t wallClockTimeUs = -1; 223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mFrameCount == 0) { 225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong memcpy(outPtr, mAudioSpecificConfigData, 2); 226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong buffer->set_range(0, 2); 227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong buffer->meta_data()->setInt32(kKeyIsCodecConfig, true); 228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *out = buffer; 229a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong ++mFrameCount; 230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return OK; 231a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong } else if (mFrameCount == 1) { 232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong buffer->meta_data()->setInt32(kKeyIsCodecConfig, false); 233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 2358fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong const int32_t nSamples = mChannels * kNumSamplesPerFrame; 2368fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong while (mNumInputSamples < nSamples) { 237065d1aff96818df54456053f1574aec8a234d0deJames Dong if (mInputBuffer == NULL) { 238065d1aff96818df54456053f1574aec8a234d0deJames Dong if (mSource->read(&mInputBuffer, options) != OK) { 239065d1aff96818df54456053f1574aec8a234d0deJames Dong if (mNumInputSamples == 0) { 240542db5d438988360d491a5add1040a2df9aa90c9James Dong buffer->release(); 241065d1aff96818df54456053f1574aec8a234d0deJames Dong return ERROR_END_OF_STREAM; 242065d1aff96818df54456053f1574aec8a234d0deJames Dong } 243065d1aff96818df54456053f1574aec8a234d0deJames Dong memset(&mInputFrame[mNumInputSamples], 244065d1aff96818df54456053f1574aec8a234d0deJames Dong 0, 2458fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong sizeof(int16_t) * (nSamples - mNumInputSamples)); 246065d1aff96818df54456053f1574aec8a234d0deJames Dong mNumInputSamples = 0; 247065d1aff96818df54456053f1574aec8a234d0deJames Dong break; 248065d1aff96818df54456053f1574aec8a234d0deJames Dong } 249065d1aff96818df54456053f1574aec8a234d0deJames Dong 250065d1aff96818df54456053f1574aec8a234d0deJames Dong size_t align = mInputBuffer->range_length() % sizeof(int16_t); 251065d1aff96818df54456053f1574aec8a234d0deJames Dong CHECK_EQ(align, 0); 252065d1aff96818df54456053f1574aec8a234d0deJames Dong 253065d1aff96818df54456053f1574aec8a234d0deJames Dong int64_t timeUs; 254caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) { 255caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong wallClockTimeUs = timeUs; 256caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong } 2573c3763d2ee1cd1fba7fe522fbaf0faca315d8c2aJames Dong if (mInputBuffer->meta_data()->findInt64(kKeyAnchorTime, &timeUs)) { 258065d1aff96818df54456053f1574aec8a234d0deJames Dong mAnchorTimeUs = timeUs; 259065d1aff96818df54456053f1574aec8a234d0deJames Dong } 260d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong readFromSource = true; 261d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong } else { 262d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong readFromSource = false; 263065d1aff96818df54456053f1574aec8a234d0deJames Dong } 2648fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong size_t copy = (nSamples - mNumInputSamples) * sizeof(int16_t); 265065d1aff96818df54456053f1574aec8a234d0deJames Dong 266065d1aff96818df54456053f1574aec8a234d0deJames Dong if (copy > mInputBuffer->range_length()) { 267065d1aff96818df54456053f1574aec8a234d0deJames Dong copy = mInputBuffer->range_length(); 268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 269065d1aff96818df54456053f1574aec8a234d0deJames Dong 270065d1aff96818df54456053f1574aec8a234d0deJames Dong memcpy(&mInputFrame[mNumInputSamples], 271065d1aff96818df54456053f1574aec8a234d0deJames Dong (const uint8_t *) mInputBuffer->data() 272065d1aff96818df54456053f1574aec8a234d0deJames Dong + mInputBuffer->range_offset(), 273065d1aff96818df54456053f1574aec8a234d0deJames Dong copy); 274065d1aff96818df54456053f1574aec8a234d0deJames Dong 275065d1aff96818df54456053f1574aec8a234d0deJames Dong mInputBuffer->set_range( 276065d1aff96818df54456053f1574aec8a234d0deJames Dong mInputBuffer->range_offset() + copy, 277065d1aff96818df54456053f1574aec8a234d0deJames Dong mInputBuffer->range_length() - copy); 278065d1aff96818df54456053f1574aec8a234d0deJames Dong 279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mInputBuffer->range_length() == 0) { 280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mInputBuffer->release(); 281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mInputBuffer = NULL; 282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 283065d1aff96818df54456053f1574aec8a234d0deJames Dong mNumInputSamples += copy / sizeof(int16_t); 2848fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong if (mNumInputSamples >= nSamples) { 2858fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong mNumInputSamples %= nSamples; 286065d1aff96818df54456053f1574aec8a234d0deJames Dong break; 287065d1aff96818df54456053f1574aec8a234d0deJames Dong } 288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 290065d1aff96818df54456053f1574aec8a234d0deJames Dong VO_CODECBUFFER inputData; 291065d1aff96818df54456053f1574aec8a234d0deJames Dong memset(&inputData, 0, sizeof(inputData)); 292065d1aff96818df54456053f1574aec8a234d0deJames Dong inputData.Buffer = (unsigned char*) mInputFrame; 2938fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong inputData.Length = nSamples * sizeof(int16_t); 294065d1aff96818df54456053f1574aec8a234d0deJames Dong CHECK(VO_ERR_NONE == mApiHandle->SetInputData(mEncoderHandle,&inputData)); 295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong VO_CODECBUFFER outputData; 297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong memset(&outputData, 0, sizeof(outputData)); 298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong VO_AUDIO_OUTPUTINFO outputInfo; 299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong memset(&outputInfo, 0, sizeof(outputInfo)); 300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong VO_U32 ret = VO_ERR_NONE; 3028fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong size_t nOutputBytes = 0; 3038fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong do { 3048fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong outputData.Buffer = outPtr; 3058fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong outputData.Length = buffer->size() - nOutputBytes; 3068fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong ret = mApiHandle->GetOutputData(mEncoderHandle, &outputData, &outputInfo); 3078fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong if (ret == VO_ERR_NONE) { 3088fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong outPtr += outputData.Length; 3098fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong nOutputBytes += outputData.Length; 3108fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong } 3118fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong } while (ret != VO_ERR_INPUT_BUFFER_SMALL); 3128fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong buffer->set_range(0, nOutputBytes); 313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 314d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong int64_t mediaTimeUs = 315d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong ((mFrameCount - 1) * 1000000LL * kNumSamplesPerFrame) / mSampleRate; 3168fff6bb0000e43f02c9d04ca90f941fdefdc1356James Dong 317d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong buffer->meta_data()->setInt64(kKeyTime, mAnchorTimeUs + mediaTimeUs); 318caa68a57f0b358b8fbe17447ffa453b9120a8610James Dong if (readFromSource && wallClockTimeUs != -1) { 319d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong buffer->meta_data()->setInt64(kKeyDriftTime, mediaTimeUs - wallClockTimeUs); 320d707fcb3e29707ca4a5935c294ef0b38eb5aba5fJames Dong } 321a7d1a2dd776bf356c228785a94ba8e0ff6a2ec7fJames Dong ++mFrameCount; 322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong *out = buffer; 324956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return OK; 325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} // namespace android 328