MediaCodecSource.cpp revision 090ef604f81447eab4aa0a5b45d6307482573560
172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang/* 272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Copyright 2014, The Android Open Source Project 372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * 472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Licensed under the Apache License, Version 2.0 (the "License"); 572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * you may not use this file except in compliance with the License. 672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * You may obtain a copy of the License at 772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * 872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * http://www.apache.org/licenses/LICENSE-2.0 972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * 1072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Unless required by applicable law or agreed to in writing, software 1172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * distributed under the License is distributed on an "AS IS" BASIS, 1272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * See the License for the specific language governing permissions and 1472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * limitations under the License. 1572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang */ 1672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang//#define LOG_NDEBUG 0 1872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#define LOG_TAG "MediaCodecSource" 1972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#define DEBUG_DRIFT_TIME 0 20a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 21a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h> 22a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn 23e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <gui/IGraphicBufferConsumer.h> 2472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <gui/IGraphicBufferProducer.h> 2572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <gui/Surface.h> 2672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/ICrypto.h> 2772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ABuffer.h> 2872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ADebug.h> 2972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ALooper.h> 3072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/AMessage.h> 3172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaBuffer.h> 3272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaCodec.h> 332e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar#include <media/stagefright/MediaCodecList.h> 34e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <media/stagefright/MediaCodecSource.h> 3572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaErrors.h> 3672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaSource.h> 37e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <media/stagefright/MetaData.h> 38e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <media/stagefright/PersistentSurface.h> 3972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/Utils.h> 4072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangnamespace android { 4272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnarconst int kDefaultSwVideoEncoderFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; 44c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnarconst int kDefaultSwVideoEncoderDataSpace = HAL_DATASPACE_BT709; 45c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 46ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnarconst int kStopTimeoutUs = 300000; // allow 1 sec for shutting down encoder 47ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 4872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource::Puller : public AHandler { 49090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh explicit Puller(const sp<MediaSource> &source); 5072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t start(const sp<MetaData> &meta, const sp<AMessage> ¬ify); 5216e79115e497386eaf010af388627f94314a55a3Chong Zhang void stop(); 53ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar void stopSource(); 5472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void pause(); 5572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void resume(); 5672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 57ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar bool readBuffer(MediaBuffer **buffer); 58ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 5972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected: 6072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang virtual void onMessageReceived(const sp<AMessage> &msg); 6172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang virtual ~Puller(); 6272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate: 6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang enum { 6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatStart = 'msta', 6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatStop, 6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatPull, 6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang }; 6972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MediaSource> mSource; 7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> mNotify; 7272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<ALooper> mLooper; 7372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bool mIsAudio; 74ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 75ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar struct Queue { 76ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Queue() 77ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar : mReadPendingSince(0), 78ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mPaused(false), 79ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mPulling(false) { } 80ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar int64_t mReadPendingSince; 81ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar bool mPaused; 82ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar bool mPulling; 83ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Vector<MediaBuffer *> mReadBuffers; 84ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 85ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar void flush(); 86ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // if queue is empty, return false and set *|buffer| to NULL . Otherwise, pop 87ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // buffer from front of the queue, place it into *|buffer| and return true. 88ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar bool readBuffer(MediaBuffer **buffer); 89ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // add a buffer to the back of the queue 90ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar void pushBuffer(MediaBuffer *mbuf); 91ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar }; 92ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Queue> mQueue; 9372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg); 9572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void schedulePull(); 9672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void handleEOS(); 9772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang DISALLOW_EVIL_CONSTRUCTORS(Puller); 9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}; 10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10172cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source) 10272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang : mSource(source), 10372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper(new ALooper()), 104ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mIsAudio(false) 105ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar{ 10672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MetaData> meta = source->getFormat(); 10772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const char *mime; 10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findCString(kKeyMIMEType, &mime)); 10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsAudio = !strncasecmp(mime, "audio/", 6); 11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->setName("pull_looper"); 11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11572cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() { 11672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->unregisterHandler(id()); 11772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->stop(); 11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 120ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnarvoid MediaCodecSource::Puller::Queue::pushBuffer(MediaBuffer *mbuf) { 121ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mReadBuffers.push_back(mbuf); 122ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar} 123ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 124ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnarbool MediaCodecSource::Puller::Queue::readBuffer(MediaBuffer **mbuf) { 125ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (mReadBuffers.empty()) { 126ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar *mbuf = NULL; 127ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar return false; 128ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 129ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar *mbuf = *mReadBuffers.begin(); 130ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mReadBuffers.erase(mReadBuffers.begin()); 131ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar return true; 132ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar} 133ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 134ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnarvoid MediaCodecSource::Puller::Queue::flush() { 135ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar MediaBuffer *mbuf; 136ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar while (readBuffer(&mbuf)) { 137ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // there are no null buffers in the queue 138ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mbuf->release(); 139ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 140ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar} 141ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 142ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnarbool MediaCodecSource::Puller::readBuffer(MediaBuffer **mbuf) { 143ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 144ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar return queue->readBuffer(mbuf); 145ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar} 146ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 14772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError( 14872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &msg) { 14972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response; 15072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = msg->postAndAwaitResponse(&response); 15172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 15272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 15472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!response->findInt32("err", &err)) { 15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 15872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 163ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnarstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> ¬ify) { 16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("puller (%s) start", mIsAudio ? "audio" : "video"); 16572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->start( 16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang false /* runOnCallingThread */, 16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang false /* canCallJava */, 16872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang PRIORITY_AUDIO); 16972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->registerHandler(this); 17072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mNotify = notify; 17172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, this); 17372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setObject("meta", meta); 17472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 17572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 17716e79115e497386eaf010af388627f94314a55a3Chong Zhangvoid MediaCodecSource::Puller::stop() { 178ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar bool interrupt = false; 179ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar { 180ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // mark stopping before actually reaching kWhatStop on the looper, so the pulling will 181ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // stop. 182ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 183ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue->mPulling = false; 184ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar interrupt = queue->mReadPendingSince && (queue->mReadPendingSince < ALooper::GetNowUs() - 1000000); 185ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue->flush(); // flush any unprocessed pulled buffers 186ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 18716e79115e497386eaf010af388627f94314a55a3Chong Zhang 188ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (interrupt) { 189ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // call source->stop if read has been pending for over a second 190ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // TODO: we should really call this if kWhatStop has not returned for more than a second. 191ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mSource->stop(); 192ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 193ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar} 19416e79115e497386eaf010af388627f94314a55a3Chong Zhang 195ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnarvoid MediaCodecSource::Puller::stopSource() { 1961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatStop, this))->post(); 19772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 19872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 19972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() { 200ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 201ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue->mPaused = true; 20272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 20372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 20472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() { 205ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 206ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue->mPaused = false; 20772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 20872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 20972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() { 210ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar (new AMessage(kWhatPull, this))->post(); 21172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 21272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 21372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() { 214ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video"); 215ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar sp<AMessage> msg = mNotify->dup(); 216ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar msg->setInt32("eos", 1); 217ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar msg->post(); 21872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 21972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 22072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) { 22172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (msg->what()) { 22272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStart: 22372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 22472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<RefBase> obj; 22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findObject("meta", &obj)); 22672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 227ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar { 228ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 229ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue->mPulling = true; 230ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 23172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 23272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mSource->start(static_cast<MetaData *>(obj.get())); 23372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 23472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == OK) { 23572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang schedulePull(); 23672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 23772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response = new AMessage; 23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->setInt32("err", err); 24072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 2413f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 24272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 24372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->postReply(replyID); 24472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 24572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 24672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 24772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStop: 24872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 249ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mSource->stop(); 25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPull: 25472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 255ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 256ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue->mReadPendingSince = ALooper::GetNowUs(); 257ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (!queue->mPulling) { 258ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar handleEOS(); 25972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 26072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 26172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 262ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue.unlock(); 263ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar MediaBuffer *mbuf = NULL; 26472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mSource->read(&mbuf); 265ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue.lock(); 26672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 267ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue->mReadPendingSince = 0; 268ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // if we need to discard buffer 269ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (!queue->mPulling || queue->mPaused || err != OK) { 270ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (mbuf != NULL) { 27172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 27272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf = NULL; 27372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 274ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (queue->mPulling && err == OK) { 275ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar msg->post(); // if simply paused, keep pulling source 276ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } else if (err == ERROR_END_OF_STREAM) { 27772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("stream ended, mbuf %p", mbuf); 278ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } else if (err != OK) { 27972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("error %d reading stream.", err); 28072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 281ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 28272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 283ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (mbuf != NULL) { 284ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue->pushBuffer(mbuf); 28572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 28672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 287ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar queue.unlock(); 28872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 289ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (mbuf != NULL) { 290ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mNotify->post(); 291ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar msg->post(); 292ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } else { 293ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar handleEOS(); 294ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 29572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 29672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 29772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 29872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 29972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang TRESPASS(); 30072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 30172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 30272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 303ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos MolnarMediaCodecSource::Output::Output() 304ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar : mEncoderReachedEOS(false), 305ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mErrorCode(OK) { 306ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar} 307ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 30872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static 30972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create( 31072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<ALooper> &looper, 31172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &format, 31272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<MediaSource> &source, 313e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang const sp<IGraphicBufferConsumer> &consumer, 31472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags) { 31572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MediaCodecSource> mediaSource = 316e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang new MediaCodecSource(looper, format, source, consumer, flags); 31772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 31872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mediaSource->init() == OK) { 31972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mediaSource; 32072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 32172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return NULL; 32272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 32372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 32472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) { 3251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, mReflector); 32672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setObject("meta", params); 32772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 32872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 32972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 33072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() { 3311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, mReflector); 332ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar return postSynchronouslyAndReturnError(msg); 33372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::pause() { 3361d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatPause, mReflector))->post(); 33772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 33872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 33972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 34072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() { 34172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 34272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mGraphicBufferProducer; 34372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 34472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 34584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaCodecSource::read( 34684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber MediaBuffer** buffer, const ReadOptions* /* options */) { 347ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Output>::Locked output(mOutput); 34872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *buffer = NULL; 350ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar while (output->mBufferQueue.size() == 0 && !output->mEncoderReachedEOS) { 351ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output.waitForCondition(output->mCond); 35272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 353ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (!output->mEncoderReachedEOS) { 354ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar *buffer = *output->mBufferQueue.begin(); 355ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mBufferQueue.erase(output->mBufferQueue.begin()); 35672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 35772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 358ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar return output->mErrorCode; 35972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 36072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 36172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) { 36272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang buffer->setObserver(0); 36372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang buffer->release(); 36472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 36572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 36672cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource( 36772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<ALooper> &looper, 36872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &outputFormat, 36972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<MediaSource> &source, 370e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang const sp<IGraphicBufferConsumer> &consumer, 37172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags) 37272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang : mLooper(looper), 37372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat(outputFormat), 37472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mMeta(new MetaData), 37572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFlags(flags), 37672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo(false), 37772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStarted(false), 37872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping(false), 37972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDoMoreWorkPending(false), 380c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat(false), 381c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mEncoderFormat(0), 382c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mEncoderDataSpace(0), 383e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang mGraphicBufferConsumer(consumer), 38472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFirstSampleTimeUs(-1ll), 385ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mGeneration(0) { 38672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mLooper != NULL); 38772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 38872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang AString mime; 38972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mOutputFormat->findString("mime", &mime)); 39072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 39172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!strncasecmp("video/", mime.c_str(), 6)) { 39272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo = true; 39372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 39472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 39572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 39672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller = new Puller(source); 39772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 39872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 39972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 40072cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() { 40172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 40272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 40372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->stop(); 40472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->unregisterHandler(mReflector->id()); 40572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 40672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 40772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() { 40872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = initEncoder(); 40972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 41172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 41272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 41372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 41572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 41672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() { 41872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mReflector = new AHandlerReflector<MediaCodecSource>(this); 41972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->registerHandler(mReflector); 42072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper = new ALooper; 42272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->setName("codec_looper"); 42372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->start(); 42472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_METADATA_INPUT) { 42672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat->setInt32("store-metadata-in-buffers", 1); 42772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat->setInt32("create-input-buffers-suspended", 1); 43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang AString outputMIME; 43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mOutputFormat->findString("mime", &outputMIME)); 43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4362e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar Vector<AString> matchingCodecs; 4372e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar MediaCodecList::findMatchingCodecs( 4382e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar outputMIME.c_str(), true /* encoder */, 4392e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar ((mFlags & FLAG_PREFER_SOFTWARE_CODEC) ? MediaCodecList::kPreferSoftwareCodecs : 0), 4402e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar &matchingCodecs); 44172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4422e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar status_t err = NO_INIT; 4432e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar for (size_t ix = 0; ix < matchingCodecs.size(); ++ix) { 4442e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar mEncoder = MediaCodec::CreateByComponentName( 4452e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar mCodecLooper, matchingCodecs[ix]); 4462e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar 4472e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar if (mEncoder == NULL) { 4482e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar continue; 4492e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar } 4502e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar 4512e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); 45272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4532e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector); 4542e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar mEncoder->setCallback(mEncoderActivityNotify); 45572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 4562e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar err = mEncoder->configure( 4572e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar mOutputFormat, 4582e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar NULL /* nativeWindow */, 4592e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar NULL /* crypto */, 4602e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar MediaCodec::CONFIGURE_FLAG_ENCODE); 461421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 4622e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar if (err == OK) { 4632e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar break; 4642e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar } 4652e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar mEncoder->release(); 4662e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar mEncoder = NULL; 4672e18508d33b845ef77676559d3bb70acc37b39eeLajos Molnar } 46872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 47072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 47172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 47272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 47372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->getOutputFormat(&mOutputFormat); 47472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang convertMessageToMetaData(mOutputFormat, mMeta); 47572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 47672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 47772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mIsVideo); 47872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 479e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang if (mGraphicBufferConsumer != NULL) { 480e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // When using persistent surface, we are only interested in the 481e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // consumer, but have to use PersistentSurface as a wrapper to 482e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // pass consumer over messages (similar to BufferProducerWrapper) 4838f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang err = mEncoder->setInputSurface( 484e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang new PersistentSurface(NULL, mGraphicBufferConsumer)); 485e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang } else { 486e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang err = mEncoder->createInputSurface(&mGraphicBufferProducer); 487e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang } 48872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 48972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 49072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 49172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 49272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 49372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 494c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar sp<AMessage> inputFormat; 495c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar int32_t usingSwReadOften; 496c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat = false; 497c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (mEncoder->getInputFormat(&inputFormat) == OK 498c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar && inputFormat->findInt32("using-sw-read-often", &usingSwReadOften) 499c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar && usingSwReadOften) { 500c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar // this is a SW encoder; signal source to allocate SW readable buffers 501c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat = true; 502c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mEncoderFormat = kDefaultSwVideoEncoderFormat; 503c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mEncoderDataSpace = kDefaultSwVideoEncoderDataSpace; 504c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 505c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 5061099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan err = mEncoder->start(); 50772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 50872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 50972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 51072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 51172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 512ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar { 513ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Output>::Locked output(mOutput); 514ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mEncoderReachedEOS = false; 515ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mErrorCode = OK; 516ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 51772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 51872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 51972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 52072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 52172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() { 52272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 52372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return; 52472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 52572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 52672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->release(); 52772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder.clear(); 52872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 52972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 53072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError( 53172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &msg) { 53272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response; 53372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = msg->postAndAwaitResponse(&response); 53472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 53572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 53672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 53772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 53872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 53972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!response->findInt32("err", &err)) { 54072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 54172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 54272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 54372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 54472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 54572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 54672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) { 547ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar bool reachedEOS = false; 548ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar { 549ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Output>::Locked output(mOutput); 550ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar reachedEOS = output->mEncoderReachedEOS; 551ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (!reachedEOS) { 552ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar ALOGV("encoder (%s) reached EOS", mIsVideo ? "video" : "audio"); 55372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // release all unread media buffers 554ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar for (List<MediaBuffer*>::iterator it = output->mBufferQueue.begin(); 555ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar it != output->mBufferQueue.end(); it++) { 55672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (*it)->release(); 55772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 558ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mBufferQueue.clear(); 559ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mEncoderReachedEOS = true; 560ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mErrorCode = err; 561ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mCond.signal(); 562ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 563ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar reachedEOS = true; 564ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output.unlock(); 565ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar releaseEncoder(); 56672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 56772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 568ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 569ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (mStopping && reachedEOS) { 57016e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio"); 571ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mPuller->stopSource(); 572ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio"); 57372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // posting reply to everyone that's waiting 5743f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar List<sp<AReplyToken>>::iterator it; 57572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang for (it = mStopReplyIDQueue.begin(); 57672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang it != mStopReplyIDQueue.end(); it++) { 57772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage)->postReply(*it); 57872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 57972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopReplyIDQueue.clear(); 58072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping = false; 581ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar ++mGeneration; 58272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 58372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 58472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 58572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::suspend() { 58672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 58772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder != NULL) { 58872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> params = new AMessage; 58972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt32("drop-input-frames", true); 59072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->setParameters(params); 59172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 59272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 59372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 59472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::resume(int64_t skipFramesBeforeUs) { 59572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 59672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder != NULL) { 59772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> params = new AMessage; 59872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt32("drop-input-frames", false); 59972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (skipFramesBeforeUs > 0) { 60072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt64("skip-frames-before", skipFramesBeforeUs); 60172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->setParameters(params); 60372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 60472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 60572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 60672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() { 607ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar MediaBuffer* mbuf = NULL; 608ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar while (!mAvailEncoderInputIndices.empty() && mPuller->readBuffer(&mbuf)) { 60972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t bufferIndex = *mAvailEncoderInputIndices.begin(); 61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin()); 61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t timeUs = 0ll; 61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags = 0; 61472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t size = 0; 61572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 61672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf != NULL) { 61772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); 61872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 61972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // push decoding time for video, or drift time for audio 62072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 62172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDecodingTimeQueue.push_back(timeUs); 62272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME 62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFirstSampleTimeUs < 0ll) { 62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFirstSampleTimeUs = timeUs; 62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t driftTimeUs = 0; 62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs) 63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang && driftTimeUs) { 63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs; 63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 63372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDriftTimeQueue.push_back(driftTimeUs); 63472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME 63572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 63672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6371099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan sp<ABuffer> inbuf; 6381099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf); 6391099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (err != OK || inbuf == NULL) { 6401099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->release(); 6411099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 6421099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 6431099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 6441099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 64572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size = mbuf->size(); 64672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan memcpy(inbuf->data(), mbuf->data(), size); 64872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 64972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 65072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // video encoder will release MediaBuffer when done 65172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // with underlying data. 6521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan inbuf->setMediaBufferBase(mbuf); 65372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 65472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 65572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 65672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 65772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang flags = MediaCodec::BUFFER_FLAG_EOS; 65872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 65972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 66072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mEncoder->queueInputBuffer( 66172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bufferIndex, 0, size, timeUs, flags); 66272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 66372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 66472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 66572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 66672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 66872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 67072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 67172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) { 67272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping) { 67372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("Failed to start while we're stopping"); 67472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return INVALID_OPERATION; 67572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 67672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 67772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStarted) { 67872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio"); 67972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 68072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang resume(); 68172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 68272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 68372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller->resume(); 68472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 68572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 68672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 68772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 68872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio"); 68972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 69072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = OK; 69172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 69272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 69372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t startTimeUs; 69472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!params || !params->findInt64(kKeyTime, &startTimeUs)) { 69572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang startTimeUs = -1ll; 69672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 69772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang resume(startTimeUs); 69872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 69972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 700c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar sp<MetaData> meta = params; 701c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (mSetEncoderFormat) { 702c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta == NULL) { 703c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta = new MetaData; 704c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 705c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta->setInt32(kKeyPixelFormat, mEncoderFormat); 706c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta->setInt32(kKeyColorSpace, mEncoderDataSpace); 707c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 708c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 7091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector); 710c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar err = mPuller->start(meta.get(), notify); 71172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 71272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 71372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 71472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 71572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 71672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio"); 71772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 71872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStarted = true; 71972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 72072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 72172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 72272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { 72372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (msg->what()) { 72472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPullerNotify: 72572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 726ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar int32_t eos = 0; 727ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (msg->findInt32("eos", &eos) && eos) { 728ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar ALOGV("puller (%s) reached EOS", mIsVideo ? "video" : "audio"); 72916e79115e497386eaf010af388627f94314a55a3Chong Zhang signalEOS(); 730ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar break; 73172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 73272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 73372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 734ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str()); 73572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 73672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 73772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 73872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang feedEncoderInputBuffers(); 73972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 74072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 74172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatEncoderActivity: 74272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 74372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 74472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 74572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 74672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t cbID; 7481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("callbackID", &cbID)); 7491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (cbID == MediaCodec::CB_INPUT_AVAILABLE) { 7501099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t index; 7511099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("index", &index)); 7521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 7531099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mAvailEncoderInputIndices.push_back(index); 7541099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan feedEncoderInputBuffers(); 7551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) { 7561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t index; 7571099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan size_t offset; 7581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan size_t size; 7591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t timeUs; 7601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t flags; 7611099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 7621099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("index", &index)); 7631099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findSize("offset", &offset)); 7641099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findSize("size", &size)); 7651099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt64("timeUs", &timeUs)); 7661099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("flags", &flags)); 7671099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 7681099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (flags & MediaCodec::BUFFER_FLAG_EOS) { 7691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mEncoder->releaseOutputBuffer(index); 7701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 7711099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 7721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 773f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang 7741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan sp<ABuffer> outbuf; 7751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err = mEncoder->getOutputBuffer(index, &outbuf); 7761099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (err != OK || outbuf == NULL) { 7771099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 7781099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 7791099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 780f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang 7811099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); 7821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan memcpy(mbuf->data(), outbuf->data(), outbuf->size()); 78372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7841099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { 7851099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (mIsVideo) { 7861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t decodingTimeUs; 7871099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (mFlags & FLAG_USE_SURFACE_INPUT) { 7881099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // GraphicBufferSource is supposed to discard samples 7891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // queued before start, and offset timeUs by start time 7901099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK_GE(timeUs, 0ll); 7911099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // TODO: 7921099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // Decoding time for surface source is unavailable, 7931099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // use presentation time for now. May need to move 7941099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // this logic into MediaCodec. 7951099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan decodingTimeUs = timeUs; 7961099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 7971099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(!mDecodingTimeQueue.empty()); 7981099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan decodingTimeUs = *(mDecodingTimeQueue.begin()); 7991099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); 8001099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8011099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); 80272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8031099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64, 8041099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan timeUs, timeUs / 1E6, decodingTimeUs - timeUs); 8051099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 8061099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t driftTimeUs = 0; 8071099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#if DEBUG_DRIFT_TIME 8081099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(!mDriftTimeQueue.empty()); 8091099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan driftTimeUs = *(mDriftTimeQueue.begin()); 8101099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mDriftTimeQueue.erase(mDriftTimeQueue.begin()); 8111099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); 8121099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#endif // DEBUG_DRIFT_TIME 8131099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64, 8141099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan timeUs, timeUs / 1E6, driftTimeUs); 8151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyTime, timeUs); 8171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 8181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); 8191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { 8211099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); 8221099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->setObserver(this); 8241099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->add_ref(); 8251099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8261099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan { 827ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar Mutexed<Output>::Locked output(mOutput); 828ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mBufferQueue.push_back(mbuf); 829ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar output->mCond.signal(); 8301099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8321099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mEncoder->releaseOutputBuffer(index); 8331099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else if (cbID == MediaCodec::CB_ERROR) { 8341099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err; 8351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("err", &err)); 8361099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGE("Encoder (%s) reported error : 0x%x", 8371099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mIsVideo ? "video" : "audio", err); 8381099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 8391099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8401099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 84172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 84272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStart: 84372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 8443f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 84572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 84672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 84772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<RefBase> obj; 84872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findObject("meta", &obj)); 84972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MetaData *params = static_cast<MetaData *>(obj.get()); 85072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 85172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response = new AMessage; 85272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->setInt32("err", onStart(params)); 85372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->postReply(replyID); 85472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 85572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 85672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStop: 85772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 85816e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio"); 85972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8603f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 86172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 86272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 863ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (mOutput.lock()->mEncoderReachedEOS) { 86472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if we already reached EOS, reply and return now 86516e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) already stopped", 86672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo ? "video" : "audio"); 86772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage)->postReply(replyID); 86872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 86972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 87072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 87172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopReplyIDQueue.push_back(replyID); 87272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping) { 87372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // nothing to do if we're already stopping, reply will be posted 87472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // to all when we're stopped. 87572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 87672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 87772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 87872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping = true; 87972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 88072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if using surface, signal source EOS and wait for EOS to come back. 881ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // otherwise, stop puller (which also clears the input buffer queue) 882ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // and wait for the EOS message. We cannot call source->stop() because 883ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // the encoder may still be processing input buffers. 88472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 88572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->signalEndOfInputStream(); 88672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 887ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mPuller->stop(); 88872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 889ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 890ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar // complete stop even if encoder/puller stalled 891ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar sp<AMessage> timeoutMsg = new AMessage(kWhatStopStalled, mReflector); 892ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar timeoutMsg->setInt32("generation", mGeneration); 893ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar timeoutMsg->post(kStopTimeoutUs); 89472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 89572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 896ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 897ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar case kWhatStopStalled: 898ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar { 899ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar int32_t generation; 900ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar CHECK(msg->findInt32("generation", &generation)); 901ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (generation != mGeneration) { 902ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar break; 903ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 904ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 905ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 906ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar ALOGV("source (%s) stopping", mIsVideo ? "video" : "audio"); 907ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar mPuller->stopSource(); 908ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio"); 909ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 910ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar signalEOS(); 911ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar } 912ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar 91372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPause: 91472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 915ea1a45dbdf7fd6f435f92d20a95f432cf3f147b5Lajos Molnar if (mFlags & FLAG_USE_SURFACE_INPUT) { 91672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang suspend(); 91772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 91872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 91972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller->pause(); 92072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 92172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 92272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 92372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 92472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang TRESPASS(); 92572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 92672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 92772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 92872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android 929