MediaCodecSource.cpp revision 4cca134f0a775808458622490886d775c59bcc54
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> 3316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos 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 43b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarconst int32_t kDefaultSwVideoEncoderFormat = HAL_PIXEL_FORMAT_YCbCr_420_888; 44b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarconst int32_t kDefaultHwVideoEncoderFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 452cbf6cea23539bfe99e36d1d221de62255452e86Eino-Ville Talvalaconst int32_t kDefaultVideoEncoderDataSpace = HAL_DATASPACE_V0_BT709; 46c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarconst int kStopTimeoutUs = 300000; // allow 1 sec for shutting down encoder 486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 4972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource::Puller : public AHandler { 5072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang Puller(const sp<MediaSource> &source); 5172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar void interruptSource(); 5372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t start(const sp<MetaData> &meta, const sp<AMessage> ¬ify); 5416e79115e497386eaf010af388627f94314a55a3Chong Zhang void stop(); 556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar void stopSource(); 5672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void pause(); 5772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void resume(); 5872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool readBuffer(MediaBuffer **buffer); 606a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 6172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected: 6272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang virtual void onMessageReceived(const sp<AMessage> &msg); 6372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang virtual ~Puller(); 6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate: 6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang enum { 6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatStart = 'msta', 6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatStop, 6972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatPull, 7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang }; 7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MediaSource> mSource; 7372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> mNotify; 7472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<ALooper> mLooper; 7572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bool mIsAudio; 766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 776a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar struct Queue { 786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Queue() 796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar : mReadPendingSince(0), 806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mPaused(false), 816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mPulling(false) { } 826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar int64_t mReadPendingSince; 836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool mPaused; 846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool mPulling; 856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Vector<MediaBuffer *> mReadBuffers; 866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar void flush(); 886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // if queue is empty, return false and set *|buffer| to NULL . Otherwise, pop 8972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar // buffer from front of the queue, place it into *|buffer| and return true. 906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool readBuffer(MediaBuffer **buffer); 9172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar // add a buffer to the back of the queue 926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar void pushBuffer(MediaBuffer *mbuf); 936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar }; 946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue> mQueue; 9572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg); 9772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void schedulePull(); 9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void handleEOS(); 9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang DISALLOW_EVIL_CONSTRUCTORS(Puller); 10172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}; 10272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10372cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source) 10472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang : mSource(source), 10572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper(new ALooper()), 1066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mIsAudio(false) 1076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar{ 10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MetaData> meta = source->getFormat(); 10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const char *mime; 11072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findCString(kKeyMIMEType, &mime)); 11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsAudio = !strncasecmp(mime, "audio/", 6); 11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->setName("pull_looper"); 11572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 11672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11772cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() { 11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->unregisterHandler(id()); 11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->stop(); 12072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 12172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::pushBuffer(MediaBuffer *mbuf) { 1236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mReadBuffers.push_back(mbuf); 1246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 1256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 1266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::Queue::readBuffer(MediaBuffer **mbuf) { 1276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mReadBuffers.empty()) { 1286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar *mbuf = NULL; 1296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return false; 1306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 1316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar *mbuf = *mReadBuffers.begin(); 1326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mReadBuffers.erase(mReadBuffers.begin()); 1336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return true; 1346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 1356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 1366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::flush() { 1376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar MediaBuffer *mbuf; 1386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar while (readBuffer(&mbuf)) { 1396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // there are no null buffers in the queue 1406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mbuf->release(); 1416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 1426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 1436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 1446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::readBuffer(MediaBuffer **mbuf) { 1456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 1466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return queue->readBuffer(mbuf); 1476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 1486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 14972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError( 15072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &msg) { 15172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response; 15272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = msg->postAndAwaitResponse(&response); 15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 15472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 15872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!response->findInt32("err", &err)) { 15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 16372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1656a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> ¬ify) { 16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("puller (%s) start", mIsAudio ? "audio" : "video"); 16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->start( 16872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang false /* runOnCallingThread */, 16972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang false /* canCallJava */, 17072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang PRIORITY_AUDIO); 17172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->registerHandler(this); 17272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mNotify = notify; 17372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, this); 17572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setObject("meta", meta); 17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 17772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 17872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 17916e79115e497386eaf010af388627f94314a55a3Chong Zhangvoid MediaCodecSource::Puller::stop() { 1806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool interrupt = false; 1816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 1826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // mark stopping before actually reaching kWhatStop on the looper, so the pulling will 1836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // stop. 1846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 1856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mPulling = false; 1866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar interrupt = queue->mReadPendingSince && (queue->mReadPendingSince < ALooper::GetNowUs() - 1000000); 1876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->flush(); // flush any unprocessed pulled buffers 1886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 18916e79115e497386eaf010af388627f94314a55a3Chong Zhang 1906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (interrupt) { 19172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar interruptSource(); 1926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 1936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 19416e79115e497386eaf010af388627f94314a55a3Chong Zhang 19572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnarvoid MediaCodecSource::Puller::interruptSource() { 19672e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar // call source->stop if read has been pending for over a second 19772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar // We have to call this outside the looper as looper is pending on the read. 19872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar mSource->stop(); 19972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar} 20072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar 2016a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::stopSource() { 20272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, this); 20372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar (void)postSynchronouslyAndReturnError(msg); 20472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 20572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 20672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() { 2076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 2086a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mPaused = true; 20972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 21072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 21172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() { 2126a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 2136a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mPaused = false; 21472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 21572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 21672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() { 2176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar (new AMessage(kWhatPull, this))->post(); 21872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 21972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 22072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() { 2216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video"); 2226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar sp<AMessage> msg = mNotify->dup(); 2236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar msg->setInt32("eos", 1); 2246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar msg->post(); 22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 22672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 22772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) { 22872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (msg->what()) { 22972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStart: 23072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 23172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<RefBase> obj; 23272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findObject("meta", &obj)); 23372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 2346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 2356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 2366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mPulling = true; 2376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mSource->start(static_cast<MetaData *>(obj.get())); 24072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 24172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == OK) { 24272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang schedulePull(); 24372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 24472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 24572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response = new AMessage; 24672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->setInt32("err", err); 24772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 2483f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 24972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->postReply(replyID); 25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 25472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStop: 25572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 2566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mSource->stop(); 25772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar 25872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar sp<AMessage> response = new AMessage; 25972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar response->setInt32("err", OK); 26072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar 26172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar sp<AReplyToken> replyID; 26272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 26372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar response->postReply(replyID); 26472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 26572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 26672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 26772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPull: 26872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 2696a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 2706a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mReadPendingSince = ALooper::GetNowUs(); 2716a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!queue->mPulling) { 2726a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar handleEOS(); 27372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 27472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 27572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 2766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue.unlock(); 2776a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar MediaBuffer *mbuf = NULL; 27872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mSource->read(&mbuf); 2796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue.lock(); 28072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 2816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mReadPendingSince = 0; 2826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // if we need to discard buffer 2836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!queue->mPulling || queue->mPaused || err != OK) { 2846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mbuf != NULL) { 28572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 28672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf = NULL; 28772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 2886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (queue->mPulling && err == OK) { 2896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar msg->post(); // if simply paused, keep pulling source 2906d6c21b8d2ed66007833dae0451b0a211c97e592Wonsik Kim break; 2916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } else if (err == ERROR_END_OF_STREAM) { 29272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("stream ended, mbuf %p", mbuf); 2936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } else if (err != OK) { 29472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("error %d reading stream.", err); 29572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 2966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 29772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 2986a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mbuf != NULL) { 2996a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->pushBuffer(mbuf); 30072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 30172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3026a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue.unlock(); 30372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3046a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mbuf != NULL) { 3056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mNotify->post(); 3066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar msg->post(); 3076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } else { 3086a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar handleEOS(); 3096a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 31072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 31172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 31272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 31372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 31472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang TRESPASS(); 31572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 31672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 31772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3186a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos MolnarMediaCodecSource::Output::Output() 3196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar : mEncoderReachedEOS(false), 3206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mErrorCode(OK) { 3216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 3226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 32372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static 32472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create( 32572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<ALooper> &looper, 32672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &format, 32772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<MediaSource> &source, 328e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang const sp<IGraphicBufferConsumer> &consumer, 32972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags) { 33072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MediaCodecSource> mediaSource = 331e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang new MediaCodecSource(looper, format, source, consumer, flags); 33272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 33372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mediaSource->init() == OK) { 33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mediaSource; 33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 33672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return NULL; 33772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 33872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 339d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kimvoid MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) { 340d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector); 341d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim msg->setInt64("time-offset-us", timeOffsetUs); 342d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim postSynchronouslyAndReturnError(msg); 343d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim} 344d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim 34572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) { 3461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, mReflector); 34772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setObject("meta", params); 34872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 35072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 35172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() { 3521d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, mReflector); 3536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return postSynchronouslyAndReturnError(msg); 35472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 35572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 35672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::pause() { 3571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatPause, mReflector))->post(); 35872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 35972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 36072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 361ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnarsp<MetaData> MediaCodecSource::getFormat() { 362ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar Mutexed<sp<MetaData>>::Locked meta(mMeta); 363ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar return *meta; 364ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar} 365ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar 36672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() { 36772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 36872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mGraphicBufferProducer; 36972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 37072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 37184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaCodecSource::read( 37284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber MediaBuffer** buffer, const ReadOptions* /* options */) { 3736a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Output>::Locked output(mOutput); 37472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 37572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *buffer = NULL; 3766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar while (output->mBufferQueue.size() == 0 && !output->mEncoderReachedEOS) { 3776a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output.waitForCondition(output->mCond); 37872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 3796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!output->mEncoderReachedEOS) { 3806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar *buffer = *output->mBufferQueue.begin(); 3816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mBufferQueue.erase(output->mBufferQueue.begin()); 38272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 38372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 3846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return output->mErrorCode; 38572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 38672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 38772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) { 38872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang buffer->setObserver(0); 38972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang buffer->release(); 39072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 39172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 39272cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource( 39372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<ALooper> &looper, 39472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &outputFormat, 39572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<MediaSource> &source, 396e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang const sp<IGraphicBufferConsumer> &consumer, 39772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags) 39872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang : mLooper(looper), 39972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat(outputFormat), 40072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mMeta(new MetaData), 40172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFlags(flags), 40272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo(false), 40372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStarted(false), 40472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping(false), 40572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDoMoreWorkPending(false), 406c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat(false), 407c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mEncoderFormat(0), 408c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mEncoderDataSpace(0), 409e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang mGraphicBufferConsumer(consumer), 410d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mInputBufferTimeOffsetUs(0), 41172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFirstSampleTimeUs(-1ll), 4126a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mGeneration(0) { 41372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mLooper != NULL); 41472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang AString mime; 41672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mOutputFormat->findString("mime", &mime)); 41772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!strncasecmp("video/", mime.c_str(), 6)) { 41972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo = true; 42072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 42172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 42372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller = new Puller(source); 42472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 42572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 42672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 42772cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() { 42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->stop(); 43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->unregisterHandler(mReflector->id()); 43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() { 43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = initEncoder(); 43672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 43972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 44072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 44172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 44272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 44372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 44472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() { 44572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mReflector = new AHandlerReflector<MediaCodecSource>(this); 44672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->registerHandler(mReflector); 44772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 44872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper = new ALooper; 44972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->setName("codec_looper"); 45072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->start(); 45172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 45272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_METADATA_INPUT) { 45372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat->setInt32("store-metadata-in-buffers", 1); 45472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 45572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 45672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 45772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat->setInt32("create-input-buffers-suspended", 1); 45872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 45972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang AString outputMIME; 46172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mOutputFormat->findString("mime", &outputMIME)); 46272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar Vector<AString> matchingCodecs; 46416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar MediaCodecList::findMatchingCodecs( 46516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar outputMIME.c_str(), true /* encoder */, 46616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar ((mFlags & FLAG_PREFER_SOFTWARE_CODEC) ? MediaCodecList::kPreferSoftwareCodecs : 0), 46716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar &matchingCodecs); 46872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar status_t err = NO_INIT; 47016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar for (size_t ix = 0; ix < matchingCodecs.size(); ++ix) { 47116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mEncoder = MediaCodec::CreateByComponentName( 47216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mCodecLooper, matchingCodecs[ix]); 47316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar 47416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar if (mEncoder == NULL) { 47516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar continue; 47616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar } 47716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar 47816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); 47972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 48016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector); 48116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mEncoder->setCallback(mEncoderActivityNotify); 48272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 48316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar err = mEncoder->configure( 48416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mOutputFormat, 48516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar NULL /* nativeWindow */, 48616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar NULL /* crypto */, 48716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar MediaCodec::CONFIGURE_FLAG_ENCODE); 488421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 48916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar if (err == OK) { 49016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar break; 49116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar } 49216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mEncoder->release(); 49316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mEncoder = NULL; 49416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar } 49572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 49672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 49772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 49872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 49972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 50072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->getOutputFormat(&mOutputFormat); 501ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar sp<MetaData> meta = new MetaData; 502ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar convertMessageToMetaData(mOutputFormat, meta); 503ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar mMeta.lock().set(meta); 50472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 50572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 50672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mIsVideo); 50772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 508e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang if (mGraphicBufferConsumer != NULL) { 509e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // When using persistent surface, we are only interested in the 510e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // consumer, but have to use PersistentSurface as a wrapper to 511e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // pass consumer over messages (similar to BufferProducerWrapper) 5128f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang err = mEncoder->setInputSurface( 513e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang new PersistentSurface(NULL, mGraphicBufferConsumer)); 514e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang } else { 515e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang err = mEncoder->createInputSurface(&mGraphicBufferProducer); 516e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang } 51772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 51872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 51972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 52072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 52172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 52272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 523c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar sp<AMessage> inputFormat; 524c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar int32_t usingSwReadOften; 525c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat = false; 526b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mEncoder->getInputFormat(&inputFormat) == OK) { 527c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat = true; 528b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (inputFormat->findInt32("using-sw-read-often", &usingSwReadOften) 529b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar && usingSwReadOften) { 530b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // this is a SW encoder; signal source to allocate SW readable buffers 531b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mEncoderFormat = kDefaultSwVideoEncoderFormat; 532b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } else { 533b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mEncoderFormat = kDefaultHwVideoEncoderFormat; 534b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 535b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (!inputFormat->findInt32("android._dataspace", &mEncoderDataSpace)) { 536b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mEncoderDataSpace = kDefaultVideoEncoderDataSpace; 537b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 538b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("setting dataspace %#x, format %#x", mEncoderDataSpace, mEncoderFormat); 539c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 540c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 5411099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan err = mEncoder->start(); 54272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 54372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 54472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 54572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 54672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 5486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Output>::Locked output(mOutput); 5496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mEncoderReachedEOS = false; 5506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mErrorCode = OK; 5516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 55272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 55372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 55472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 55572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 55672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() { 55772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 55872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return; 55972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 56072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 56172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->release(); 56272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder.clear(); 56372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 56472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 56572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError( 56672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &msg) { 56772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response; 56872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = msg->postAndAwaitResponse(&response); 56972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 57072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 57172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 57272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 57372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 57472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!response->findInt32("err", &err)) { 57572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 57672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 57772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 57872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 57972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 58072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 58172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) { 5826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool reachedEOS = false; 5836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 5846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Output>::Locked output(mOutput); 5856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar reachedEOS = output->mEncoderReachedEOS; 5866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!reachedEOS) { 5876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("encoder (%s) reached EOS", mIsVideo ? "video" : "audio"); 58872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // release all unread media buffers 5896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar for (List<MediaBuffer*>::iterator it = output->mBufferQueue.begin(); 5906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar it != output->mBufferQueue.end(); it++) { 59172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (*it)->release(); 59272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 5936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mBufferQueue.clear(); 5946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mEncoderReachedEOS = true; 5956a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mErrorCode = err; 5966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mCond.signal(); 5976a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 5986a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar reachedEOS = true; 5996a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output.unlock(); 6006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar releaseEncoder(); 60172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 6036a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 6046a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mStopping && reachedEOS) { 60516e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio"); 6066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mPuller->stopSource(); 6076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio"); 60872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // posting reply to everyone that's waiting 6093f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar List<sp<AReplyToken>>::iterator it; 61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang for (it = mStopReplyIDQueue.begin(); 61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang it != mStopReplyIDQueue.end(); it++) { 61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage)->postReply(*it); 61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 61472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopReplyIDQueue.clear(); 61572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping = false; 6166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ++mGeneration; 61772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 61872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 61972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::suspend() { 62172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 62272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder != NULL) { 62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> params = new AMessage; 62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt32("drop-input-frames", true); 62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->setParameters(params); 62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::resume(int64_t skipFramesBeforeUs) { 63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder != NULL) { 63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> params = new AMessage; 63372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt32("drop-input-frames", false); 63472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (skipFramesBeforeUs > 0) { 63572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt64("skip-frames-before", skipFramesBeforeUs); 63672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 63772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->setParameters(params); 63872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 63972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 64072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 64172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() { 6426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar MediaBuffer* mbuf = NULL; 6436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar while (!mAvailEncoderInputIndices.empty() && mPuller->readBuffer(&mbuf)) { 64472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t bufferIndex = *mAvailEncoderInputIndices.begin(); 64572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin()); 64672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 64772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t timeUs = 0ll; 64872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags = 0; 64972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t size = 0; 65072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 65172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf != NULL) { 65272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); 653d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim timeUs += mInputBufferTimeOffsetUs; 65472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 65572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // push decoding time for video, or drift time for audio 65672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 65772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDecodingTimeQueue.push_back(timeUs); 65872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 65972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME 66072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFirstSampleTimeUs < 0ll) { 66172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFirstSampleTimeUs = timeUs; 66272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 66372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 66472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t driftTimeUs = 0; 66572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs) 66672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang && driftTimeUs) { 66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs; 66872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDriftTimeQueue.push_back(driftTimeUs); 67072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME 67172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 67272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan sp<ABuffer> inbuf; 6741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf); 6751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (err != OK || inbuf == NULL) { 6761099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->release(); 6771099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 6781099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 6791099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 6801099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 68172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size = mbuf->size(); 68272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan memcpy(inbuf->data(), mbuf->data(), size); 68472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 68572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 68672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // video encoder will release MediaBuffer when done 68772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // with underlying data. 6881099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan inbuf->setMediaBufferBase(mbuf); 68972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 69072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 69172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 69272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 69372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang flags = MediaCodec::BUFFER_FLAG_EOS; 69472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 69572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 69672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mEncoder->queueInputBuffer( 69772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bufferIndex, 0, size, timeUs, flags); 69872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 69972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 70072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 70172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 70272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 70372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 70472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 70572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 70672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 70772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) { 70872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping) { 70972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("Failed to start while we're stopping"); 71072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return INVALID_OPERATION; 71172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 71272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 71372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStarted) { 71472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio"); 7154cca134f0a775808458622490886d775c59bcc54Wonsik Kim if (mIsVideo) { 7164cca134f0a775808458622490886d775c59bcc54Wonsik Kim mEncoder->requestIDRFrame(); 7174cca134f0a775808458622490886d775c59bcc54Wonsik Kim } 71872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 71972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang resume(); 72072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 72172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 72272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller->resume(); 72372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 72472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 72572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 72672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 72772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio"); 72872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 72972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = OK; 73072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 73172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 73272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t startTimeUs; 73372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!params || !params->findInt64(kKeyTime, &startTimeUs)) { 73472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang startTimeUs = -1ll; 73572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 73672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang resume(startTimeUs); 73772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 73872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 739c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar sp<MetaData> meta = params; 740c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (mSetEncoderFormat) { 741c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta == NULL) { 742c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta = new MetaData; 743c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 744c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta->setInt32(kKeyPixelFormat, mEncoderFormat); 745c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta->setInt32(kKeyColorSpace, mEncoderDataSpace); 746c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 747c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 7481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector); 749c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar err = mPuller->start(meta.get(), notify); 75072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 75172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 75272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 75372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 75472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 75572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio"); 75672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 75772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStarted = true; 75872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 75972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 76072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 76172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { 76272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (msg->what()) { 76372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPullerNotify: 76472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 7656a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar int32_t eos = 0; 7666a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (msg->findInt32("eos", &eos) && eos) { 7676a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("puller (%s) reached EOS", mIsVideo ? "video" : "audio"); 76816e79115e497386eaf010af388627f94314a55a3Chong Zhang signalEOS(); 7696a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar break; 77072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 77172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 77272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 7736a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str()); 77472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 77572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 77672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 77772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang feedEncoderInputBuffers(); 77872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 77972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 78072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatEncoderActivity: 78172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 78272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 78372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 78472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 78572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t cbID; 7871099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("callbackID", &cbID)); 7881099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (cbID == MediaCodec::CB_INPUT_AVAILABLE) { 7891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t index; 7901099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("index", &index)); 7911099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 7921099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mAvailEncoderInputIndices.push_back(index); 7931099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan feedEncoderInputBuffers(); 79458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } else if (cbID == MediaCodec::CB_OUTPUT_FORMAT_CHANGED) { 79558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar status_t err = mEncoder->getOutputFormat(&mOutputFormat); 79658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (err != OK) { 79758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar signalEOS(err); 79858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar break; 79958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 800ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar sp<MetaData> meta = new MetaData; 801ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar convertMessageToMetaData(mOutputFormat, meta); 802ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar mMeta.lock().set(meta); 8031099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) { 8041099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t index; 8051099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan size_t offset; 8061099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan size_t size; 8071099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t timeUs; 8081099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t flags; 8091099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8101099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("index", &index)); 8111099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findSize("offset", &offset)); 8121099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findSize("size", &size)); 8131099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt64("timeUs", &timeUs)); 8141099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("flags", &flags)); 8151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (flags & MediaCodec::BUFFER_FLAG_EOS) { 8171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mEncoder->releaseOutputBuffer(index); 8181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 8191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 8201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 821f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang 8221099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan sp<ABuffer> outbuf; 8231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err = mEncoder->getOutputBuffer(index, &outbuf); 8241099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (err != OK || outbuf == NULL) { 8251099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 8261099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 8271099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 828f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang 8291099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); 8301099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan memcpy(mbuf->data(), outbuf->data(), outbuf->size()); 83172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8321099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { 8331099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (mIsVideo) { 8341099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t decodingTimeUs; 8351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (mFlags & FLAG_USE_SURFACE_INPUT) { 836d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim // Time offset is not applied at 837d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim // feedEncoderInputBuffer() in surface input case. 838d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim timeUs += mInputBufferTimeOffsetUs; 8391099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // GraphicBufferSource is supposed to discard samples 8401099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // queued before start, and offset timeUs by start time 8411099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK_GE(timeUs, 0ll); 8421099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // TODO: 8431099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // Decoding time for surface source is unavailable, 8441099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // use presentation time for now. May need to move 8451099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // this logic into MediaCodec. 8461099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan decodingTimeUs = timeUs; 8471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 8481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(!mDecodingTimeQueue.empty()); 8491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan decodingTimeUs = *(mDecodingTimeQueue.begin()); 8501099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); 8511099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); 85372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8541099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64, 8551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan timeUs, timeUs / 1E6, decodingTimeUs - timeUs); 8561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 8571099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t driftTimeUs = 0; 8581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#if DEBUG_DRIFT_TIME 8591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(!mDriftTimeQueue.empty()); 8601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan driftTimeUs = *(mDriftTimeQueue.begin()); 8611099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mDriftTimeQueue.erase(mDriftTimeQueue.begin()); 8621099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); 8631099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#endif // DEBUG_DRIFT_TIME 8641099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64, 8651099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan timeUs, timeUs / 1E6, driftTimeUs); 8661099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8671099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyTime, timeUs); 8681099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 8691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); 8701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8711099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { 8721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); 8731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->setObserver(this); 8751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->add_ref(); 8761099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8771099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan { 8786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Output>::Locked output(mOutput); 8796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mBufferQueue.push_back(mbuf); 8806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mCond.signal(); 8811099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mEncoder->releaseOutputBuffer(index); 8841099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else if (cbID == MediaCodec::CB_ERROR) { 8851099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err; 8861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("err", &err)); 8871099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGE("Encoder (%s) reported error : 0x%x", 8881099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mIsVideo ? "video" : "audio", err); 8891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 8901099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 8911099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 89272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 89372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStart: 89472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 8953f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 89672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 89772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 89872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<RefBase> obj; 89972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findObject("meta", &obj)); 90072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MetaData *params = static_cast<MetaData *>(obj.get()); 90172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 90272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response = new AMessage; 90372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->setInt32("err", onStart(params)); 90472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->postReply(replyID); 90572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 90672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 90772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStop: 90872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 90916e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio"); 91072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9113f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 91272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 91372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9146a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mOutput.lock()->mEncoderReachedEOS) { 91572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if we already reached EOS, reply and return now 91616e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) already stopped", 91772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo ? "video" : "audio"); 91872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage)->postReply(replyID); 91972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 92072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 92172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 92272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopReplyIDQueue.push_back(replyID); 92372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping) { 92472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // nothing to do if we're already stopping, reply will be posted 92572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // to all when we're stopped. 92672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 92772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 92872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 92972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping = true; 93072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 93172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if using surface, signal source EOS and wait for EOS to come back. 9326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // otherwise, stop puller (which also clears the input buffer queue) 9336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // and wait for the EOS message. We cannot call source->stop() because 9346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // the encoder may still be processing input buffers. 93572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 93672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->signalEndOfInputStream(); 93772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 9386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mPuller->stop(); 93972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 9406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 9416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // complete stop even if encoder/puller stalled 9426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar sp<AMessage> timeoutMsg = new AMessage(kWhatStopStalled, mReflector); 9436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar timeoutMsg->setInt32("generation", mGeneration); 9446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar timeoutMsg->post(kStopTimeoutUs); 94572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 94672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 9476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 9486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar case kWhatStopStalled: 9496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 9506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar int32_t generation; 9516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar CHECK(msg->findInt32("generation", &generation)); 9526a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (generation != mGeneration) { 9536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar break; 9546a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 9556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 9566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 9576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("source (%s) stopping", mIsVideo ? "video" : "audio"); 95872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar mPuller->interruptSource(); 9596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio"); 9606a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 9616a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar signalEOS(); 9626a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 9636a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 96472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPause: 96572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 966d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim if (mFlags & FLAG_USE_SURFACE_INPUT) { 96772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang suspend(); 96872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 96972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 97072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller->pause(); 97172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 97272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 97372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 974d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim case kWhatSetInputBufferTimeOffset: 975d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim { 976d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<AReplyToken> replyID; 977d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim CHECK(msg->senderAwaitsResponse(&replyID)); 978d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim 979d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs)); 980d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim 981d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<AMessage> response = new AMessage; 982d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim response->postReply(replyID); 983d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim break; 984d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim } 98572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 98672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang TRESPASS(); 98772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 98872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 98972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 99072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android 991