AACEncoder.cpp revision f1d5aa162c02a16b7195a43a9bcea4d592600ac4
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 25f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include <media/stagefright/MediaBufferGroup.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(¶ms, 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, ¶ms)) { 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 117f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong int32_t index = 0; 118f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ((status_t)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 145f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ((status_t)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) { 186f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ((VO_U32)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; 226f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), (status_t)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); 258f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK_EQ(align, (size_t)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