MediaCodecSource.cpp revision bc8f53b8c1c220d9ce01526b6e3834f14af98ed5
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 2372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <gui/IGraphicBufferProducer.h> 2472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <gui/Surface.h> 2572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/ICrypto.h> 26bc8f53b8c1c220d9ce01526b6e3834f14af98ed5Dongwon Kang#include <media/MediaBufferHolder.h> 277e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h> 28d91dc5a0602f54fc0d4d2187f37b5b8169bb62c3Dongwon Kang#include <media/MediaSource.h> 2972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ABuffer.h> 3072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ADebug.h> 3172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ALooper.h> 3272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/AMessage.h> 3372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaBuffer.h> 3472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaCodec.h> 3516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar#include <media/stagefright/MediaCodecList.h> 36e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <media/stagefright/MediaCodecSource.h> 3772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaErrors.h> 38e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <media/stagefright/MetaData.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 48cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang// allow maximum 1 sec for stop time offset. This limits the the delay in the 49cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang// input source. 50cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuangconst int kMaxStopTimeOffsetUs = 1000000; 516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 5272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource::Puller : public AHandler { 53090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh explicit Puller(const sp<MediaSource> &source); 5472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar void interruptSource(); 5672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t start(const sp<MetaData> &meta, const sp<AMessage> ¬ify); 5716e79115e497386eaf010af388627f94314a55a3Chong Zhang void stop(); 586a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar void stopSource(); 5972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void pause(); 6072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void resume(); 61f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang status_t setStopTimeUs(int64_t stopTimeUs); 626a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool readBuffer(MediaBuffer **buffer); 636a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected: 6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang virtual void onMessageReceived(const sp<AMessage> &msg); 6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang virtual ~Puller(); 6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate: 6972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang enum { 7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatStart = 'msta', 7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatStop, 7272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang kWhatPull, 73f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang kWhatSetStopTimeUs, 7472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang }; 7572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MediaSource> mSource; 7772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> mNotify; 7872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<ALooper> mLooper; 7972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bool mIsAudio; 806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar struct Queue { 826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Queue() 836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar : mReadPendingSince(0), 846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mPaused(false), 856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mPulling(false) { } 866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar int64_t mReadPendingSince; 876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool mPaused; 886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool mPulling; 896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Vector<MediaBuffer *> mReadBuffers; 906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar void flush(); 926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // if queue is empty, return false and set *|buffer| to NULL . Otherwise, pop 9372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar // buffer from front of the queue, place it into *|buffer| and return true. 946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool readBuffer(MediaBuffer **buffer); 9572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar // add a buffer to the back of the queue 966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar void pushBuffer(MediaBuffer *mbuf); 976a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar }; 986a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue> mQueue; 9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg); 10172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void schedulePull(); 10272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang void handleEOS(); 10372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang DISALLOW_EVIL_CONSTRUCTORS(Puller); 10572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}; 10672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10772cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source) 10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang : mSource(source), 10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper(new ALooper()), 1106a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mIsAudio(false) 1116a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar{ 11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<MetaData> meta = source->getFormat(); 11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const char *mime; 11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(meta->findCString(kKeyMIMEType, &mime)); 11572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsAudio = !strncasecmp(mime, "audio/", 6); 11772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->setName("pull_looper"); 11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 12072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 12172cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() { 12272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->unregisterHandler(id()); 12372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->stop(); 12472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 12572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::pushBuffer(MediaBuffer *mbuf) { 1276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mReadBuffers.push_back(mbuf); 1286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 1296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 1306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::Queue::readBuffer(MediaBuffer **mbuf) { 1316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mReadBuffers.empty()) { 1326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar *mbuf = NULL; 1336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return false; 1346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 1356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar *mbuf = *mReadBuffers.begin(); 1366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mReadBuffers.erase(mReadBuffers.begin()); 1376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return true; 1386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 1396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 1406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::flush() { 1416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar MediaBuffer *mbuf; 1426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar while (readBuffer(&mbuf)) { 1436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // there are no null buffers in the queue 1446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mbuf->release(); 1456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 1466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 1476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 1486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::readBuffer(MediaBuffer **mbuf) { 1496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 1506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return queue->readBuffer(mbuf); 1516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 1526a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError( 15472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &msg) { 15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response; 15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = msg->postAndAwaitResponse(&response); 15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 15872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!response->findInt32("err", &err)) { 16372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 16572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 16872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 169f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuangstatus_t MediaCodecSource::Puller::setStopTimeUs(int64_t stopTimeUs) { 170f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, this); 171f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang msg->setInt64("stop-time-us", stopTimeUs); 172f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang return postSynchronouslyAndReturnError(msg); 173f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang} 174f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang 1756a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> ¬ify) { 17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("puller (%s) start", mIsAudio ? "audio" : "video"); 17772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->start( 17872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang false /* runOnCallingThread */, 17972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang false /* canCallJava */, 18072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang PRIORITY_AUDIO); 18172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->registerHandler(this); 18272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mNotify = notify; 18372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1841d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, this); 18572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setObject("meta", meta); 18672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 18772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 18872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 18916e79115e497386eaf010af388627f94314a55a3Chong Zhangvoid MediaCodecSource::Puller::stop() { 1906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool interrupt = false; 1916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 1926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // mark stopping before actually reaching kWhatStop on the looper, so the pulling will 1936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // stop. 1946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 1956a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mPulling = false; 1966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar interrupt = queue->mReadPendingSince && (queue->mReadPendingSince < ALooper::GetNowUs() - 1000000); 1976a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->flush(); // flush any unprocessed pulled buffers 1986a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 19916e79115e497386eaf010af388627f94314a55a3Chong Zhang 2006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (interrupt) { 20172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar interruptSource(); 2026a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 2036a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 20416e79115e497386eaf010af388627f94314a55a3Chong Zhang 20572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnarvoid MediaCodecSource::Puller::interruptSource() { 20672e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar // call source->stop if read has been pending for over a second 20772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar // We have to call this outside the looper as looper is pending on the read. 20872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar mSource->stop(); 20972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar} 21072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar 2116a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::stopSource() { 21272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, this); 21372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar (void)postSynchronouslyAndReturnError(msg); 21472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 21572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 21672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() { 2176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 2186a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mPaused = true; 21972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 22072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 22172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() { 2226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 2236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mPaused = false; 22472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 22672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() { 2276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar (new AMessage(kWhatPull, this))->post(); 22872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 22972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 23072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() { 2316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video"); 2326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar sp<AMessage> msg = mNotify->dup(); 2336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar msg->setInt32("eos", 1); 2346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar msg->post(); 23572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 23672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 23772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) { 23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (msg->what()) { 23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStart: 24072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 24172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<RefBase> obj; 24272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findObject("meta", &obj)); 24372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 2446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 2456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 2466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mPulling = true; 2476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 24872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 24972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mSource->start(static_cast<MetaData *>(obj.get())); 25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err == OK) { 25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang schedulePull(); 25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 25472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 25572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response = new AMessage; 25672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->setInt32("err", err); 25772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 2583f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 25972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 26072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->postReply(replyID); 26172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 26272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 26372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 264f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang case kWhatSetStopTimeUs: 265f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang { 266f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang sp<AReplyToken> replyID; 267f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang CHECK(msg->senderAwaitsResponse(&replyID)); 268f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang int64_t stopTimeUs; 269f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang CHECK(msg->findInt64("stop-time-us", &stopTimeUs)); 270f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang status_t err = mSource->setStopTimeUs(stopTimeUs); 271f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang 272f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang sp<AMessage> response = new AMessage; 273f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang response->setInt32("err", err); 274f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang response->postReply(replyID); 275f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang break; 276f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang } 277f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang 27872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStop: 27972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 2806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mSource->stop(); 28172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar 28272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar sp<AMessage> response = new AMessage; 28372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar response->setInt32("err", OK); 28472e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar 28572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar sp<AReplyToken> replyID; 28672e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 28772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar response->postReply(replyID); 28872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 28972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 29072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 29172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPull: 29272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 2936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Queue>::Locked queue(mQueue); 2946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mReadPendingSince = ALooper::GetNowUs(); 2956a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!queue->mPulling) { 2966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar handleEOS(); 29772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 29872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 29972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue.unlock(); 3016a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar MediaBuffer *mbuf = NULL; 30272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mSource->read(&mbuf); 3036a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue.lock(); 30472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->mReadPendingSince = 0; 3066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // if we need to discard buffer 3076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!queue->mPulling || queue->mPaused || err != OK) { 3086a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mbuf != NULL) { 30972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 31072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf = NULL; 31172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 3126a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (queue->mPulling && err == OK) { 3136a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar msg->post(); // if simply paused, keep pulling source 3146d6c21b8d2ed66007833dae0451b0a211c97e592Wonsik Kim break; 3156a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } else if (err == ERROR_END_OF_STREAM) { 31672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGV("stream ended, mbuf %p", mbuf); 3176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } else if (err != OK) { 31872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("error %d reading stream.", err); 31972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 3206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 32172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mbuf != NULL) { 3236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue->pushBuffer(mbuf); 32472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 32572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar queue.unlock(); 32772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mbuf != NULL) { 3296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mNotify->post(); 3306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar msg->post(); 3316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } else { 3326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar handleEOS(); 3336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 33672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 33772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 33872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang TRESPASS(); 33972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 34072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 34172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 3426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos MolnarMediaCodecSource::Output::Output() 3436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar : mEncoderReachedEOS(false), 3446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mErrorCode(OK) { 3456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar} 3466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 34772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static 34872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create( 34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<ALooper> &looper, 35072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &format, 35172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<MediaSource> &source, 352addf2cbb120346ae42e78fa739245a353db5edadChong Zhang const sp<PersistentSurface> &persistentSurface, 35372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags) { 354addf2cbb120346ae42e78fa739245a353db5edadChong Zhang sp<MediaCodecSource> mediaSource = new MediaCodecSource( 355addf2cbb120346ae42e78fa739245a353db5edadChong Zhang looper, format, source, persistentSurface, flags); 35672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 35772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mediaSource->init() == OK) { 35872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mediaSource; 35972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 36072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return NULL; 36172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 36272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 36361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuangstatus_t MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) { 364d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector); 365d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim msg->setInt64("time-offset-us", timeOffsetUs); 36661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang return postSynchronouslyAndReturnError(msg); 367d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim} 368d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim 369a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kimint64_t MediaCodecSource::getFirstSampleSystemTimeUs() { 370a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim sp<AMessage> msg = new AMessage(kWhatGetFirstSampleSystemTimeUs, mReflector); 371a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim sp<AMessage> response; 372a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim msg->postAndAwaitResponse(&response); 373a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim int64_t timeUs; 374a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (!response->findInt64("time-us", &timeUs)) { 375a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim timeUs = -1ll; 376a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 377a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim return timeUs; 378a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim} 379a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim 38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) { 3811d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, mReflector); 38272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang msg->setObject("meta", params); 38372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return postSynchronouslyAndReturnError(msg); 38472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 38572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 38672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() { 3871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, mReflector); 3886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return postSynchronouslyAndReturnError(msg); 38972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 39072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 391764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang 392f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuangstatus_t MediaCodecSource::setStopTimeUs(int64_t stopTimeUs) { 393f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, mReflector); 394764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang msg->setInt64("stop-time-us", stopTimeUs); 395764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang return postSynchronouslyAndReturnError(msg); 396764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang} 397764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang 398764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangstatus_t MediaCodecSource::pause(MetaData* params) { 399764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<AMessage> msg = new AMessage(kWhatPause, mReflector); 400764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang msg->setObject("meta", params); 401764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang msg->post(); 40272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 40372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 40472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 405ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnarsp<MetaData> MediaCodecSource::getFormat() { 406ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar Mutexed<sp<MetaData>>::Locked meta(mMeta); 407ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar return *meta; 408ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar} 409ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar 41072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() { 41172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 41272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return mGraphicBufferProducer; 41372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 41472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaCodecSource::read( 41684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber MediaBuffer** buffer, const ReadOptions* /* options */) { 4176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Output>::Locked output(mOutput); 41872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 41972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *buffer = NULL; 4206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar while (output->mBufferQueue.size() == 0 && !output->mEncoderReachedEOS) { 4216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output.waitForCondition(output->mCond); 42272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 4236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!output->mEncoderReachedEOS) { 4246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar *buffer = *output->mBufferQueue.begin(); 4256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mBufferQueue.erase(output->mBufferQueue.begin()); 42672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 42772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 4286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar return output->mErrorCode; 42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) { 43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang buffer->setObserver(0); 43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang buffer->release(); 43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 43672cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource( 43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<ALooper> &looper, 43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &outputFormat, 43972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<MediaSource> &source, 440addf2cbb120346ae42e78fa739245a353db5edadChong Zhang const sp<PersistentSurface> &persistentSurface, 44172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags) 44272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang : mLooper(looper), 44372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat(outputFormat), 44472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mMeta(new MetaData), 44572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFlags(flags), 44672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo(false), 44772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStarted(false), 44872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping(false), 44972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDoMoreWorkPending(false), 450c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat(false), 451c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mEncoderFormat(0), 452c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mEncoderDataSpace(0), 453addf2cbb120346ae42e78fa739245a353db5edadChong Zhang mPersistentSurface(persistentSurface), 454d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim mInputBufferTimeOffsetUs(0), 455a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mFirstSampleSystemTimeUs(-1ll), 456a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mPausePending(false), 45772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFirstSampleTimeUs(-1ll), 4586a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mGeneration(0) { 45972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mLooper != NULL); 46072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 46272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller = new Puller(source); 46372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 46472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 46572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46672cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() { 46772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 46872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 46972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->stop(); 47072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->unregisterHandler(mReflector->id()); 47172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 47272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 47372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() { 47472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = initEncoder(); 47572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 47672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 47772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang releaseEncoder(); 47872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 47972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 48072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 48172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 48272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 48372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() { 48420db1647e6062631e93f8040a352950b5960dd8eWonsik Kim 48572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mReflector = new AHandlerReflector<MediaCodecSource>(this); 48672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mLooper->registerHandler(mReflector); 48772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 48872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper = new ALooper; 48972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->setName("codec_looper"); 49072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mCodecLooper->start(); 49172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 49272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 49372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mOutputFormat->setInt32("create-input-buffers-suspended", 1); 49472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 49572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 49672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang AString outputMIME; 49772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mOutputFormat->findString("mime", &outputMIME)); 49820db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mIsVideo = outputMIME.startsWithIgnoreCase("video/"); 49972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 50020db1647e6062631e93f8040a352950b5960dd8eWonsik Kim AString name; 50116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar status_t err = NO_INIT; 50220db1647e6062631e93f8040a352950b5960dd8eWonsik Kim if (mOutputFormat->findString("testing-name", &name)) { 50320db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mEncoder = MediaCodec::CreateByComponentName(mCodecLooper, name); 50472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 50516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector); 50616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mEncoder->setCallback(mEncoderActivityNotify); 50772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 50816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar err = mEncoder->configure( 50916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar mOutputFormat, 51016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar NULL /* nativeWindow */, 51116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar NULL /* crypto */, 51216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar MediaCodec::CONFIGURE_FLAG_ENCODE); 51320db1647e6062631e93f8040a352950b5960dd8eWonsik Kim } else { 51420db1647e6062631e93f8040a352950b5960dd8eWonsik Kim Vector<AString> matchingCodecs; 51520db1647e6062631e93f8040a352950b5960dd8eWonsik Kim MediaCodecList::findMatchingCodecs( 51620db1647e6062631e93f8040a352950b5960dd8eWonsik Kim outputMIME.c_str(), true /* encoder */, 51720db1647e6062631e93f8040a352950b5960dd8eWonsik Kim ((mFlags & FLAG_PREFER_SOFTWARE_CODEC) ? MediaCodecList::kPreferSoftwareCodecs : 0), 51820db1647e6062631e93f8040a352950b5960dd8eWonsik Kim &matchingCodecs); 51920db1647e6062631e93f8040a352950b5960dd8eWonsik Kim 52020db1647e6062631e93f8040a352950b5960dd8eWonsik Kim for (size_t ix = 0; ix < matchingCodecs.size(); ++ix) { 52120db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mEncoder = MediaCodec::CreateByComponentName( 52220db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mCodecLooper, matchingCodecs[ix]); 52320db1647e6062631e93f8040a352950b5960dd8eWonsik Kim 52420db1647e6062631e93f8040a352950b5960dd8eWonsik Kim if (mEncoder == NULL) { 52520db1647e6062631e93f8040a352950b5960dd8eWonsik Kim continue; 52620db1647e6062631e93f8040a352950b5960dd8eWonsik Kim } 527421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen 52820db1647e6062631e93f8040a352950b5960dd8eWonsik Kim ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); 52920db1647e6062631e93f8040a352950b5960dd8eWonsik Kim 53020db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector); 53120db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mEncoder->setCallback(mEncoderActivityNotify); 53220db1647e6062631e93f8040a352950b5960dd8eWonsik Kim 53320db1647e6062631e93f8040a352950b5960dd8eWonsik Kim err = mEncoder->configure( 53420db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mOutputFormat, 53520db1647e6062631e93f8040a352950b5960dd8eWonsik Kim NULL /* nativeWindow */, 53620db1647e6062631e93f8040a352950b5960dd8eWonsik Kim NULL /* crypto */, 53720db1647e6062631e93f8040a352950b5960dd8eWonsik Kim MediaCodec::CONFIGURE_FLAG_ENCODE); 53820db1647e6062631e93f8040a352950b5960dd8eWonsik Kim 53920db1647e6062631e93f8040a352950b5960dd8eWonsik Kim if (err == OK) { 54020db1647e6062631e93f8040a352950b5960dd8eWonsik Kim break; 54120db1647e6062631e93f8040a352950b5960dd8eWonsik Kim } 54220db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mEncoder->release(); 54320db1647e6062631e93f8040a352950b5960dd8eWonsik Kim mEncoder = NULL; 54416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar } 54516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar } 54672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 54772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 54872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 54972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 55072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 55172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->getOutputFormat(&mOutputFormat); 552ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar sp<MetaData> meta = new MetaData; 553ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar convertMessageToMetaData(mOutputFormat, meta); 554ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar mMeta.lock().set(meta); 55572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 55672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 55772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mIsVideo); 55872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 559addf2cbb120346ae42e78fa739245a353db5edadChong Zhang if (mPersistentSurface != NULL) { 560e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // When using persistent surface, we are only interested in the 561e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // consumer, but have to use PersistentSurface as a wrapper to 562e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang // pass consumer over messages (similar to BufferProducerWrapper) 563addf2cbb120346ae42e78fa739245a353db5edadChong Zhang err = mEncoder->setInputSurface(mPersistentSurface); 564e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang } else { 565e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang err = mEncoder->createInputSurface(&mGraphicBufferProducer); 566e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang } 56772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 56872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 56972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 57072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 57172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 57272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 573c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar sp<AMessage> inputFormat; 574c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar int32_t usingSwReadOften; 575c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat = false; 576b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mEncoder->getInputFormat(&inputFormat) == OK) { 577c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar mSetEncoderFormat = true; 578b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (inputFormat->findInt32("using-sw-read-often", &usingSwReadOften) 579b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar && usingSwReadOften) { 580b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // this is a SW encoder; signal source to allocate SW readable buffers 581b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mEncoderFormat = kDefaultSwVideoEncoderFormat; 582b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } else { 583b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mEncoderFormat = kDefaultHwVideoEncoderFormat; 584b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 585b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (!inputFormat->findInt32("android._dataspace", &mEncoderDataSpace)) { 586b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mEncoderDataSpace = kDefaultVideoEncoderDataSpace; 587b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 588b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("setting dataspace %#x, format %#x", mEncoderDataSpace, mEncoderFormat); 589c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 590c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 5911099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan err = mEncoder->start(); 59272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 59372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 59472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 59572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 59672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 5976a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 5986a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Output>::Locked output(mOutput); 5996a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mEncoderReachedEOS = false; 6006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mErrorCode = OK; 6016a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 60372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 60472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 60572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 60672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() { 60772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 60872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return; 60972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->release(); 61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder.clear(); 61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 61472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 61572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError( 61672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang const sp<AMessage> &msg) { 61772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response; 61872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = msg->postAndAwaitResponse(&response); 61972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 62172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 62272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (!response->findInt32("err", &err)) { 62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang err = OK; 62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) { 6326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar bool reachedEOS = false; 6336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 6346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Output>::Locked output(mOutput); 6356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar reachedEOS = output->mEncoderReachedEOS; 6366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!reachedEOS) { 6376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("encoder (%s) reached EOS", mIsVideo ? "video" : "audio"); 63872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // release all unread media buffers 6396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar for (List<MediaBuffer*>::iterator it = output->mBufferQueue.begin(); 6406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar it != output->mBufferQueue.end(); it++) { 64172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (*it)->release(); 64272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 6436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mBufferQueue.clear(); 6446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mEncoderReachedEOS = true; 6456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mErrorCode = err; 6466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mCond.signal(); 6476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 6486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar reachedEOS = true; 6496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output.unlock(); 6506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar releaseEncoder(); 65172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 65272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 6536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 6546a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mStopping && reachedEOS) { 65516e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio"); 656522e43188628dc30287e3f8c69b779ecc885e7c2Ray Essick if (mPuller != NULL) { 657522e43188628dc30287e3f8c69b779ecc885e7c2Ray Essick mPuller->stopSource(); 658522e43188628dc30287e3f8c69b779ecc885e7c2Ray Essick } 6596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio"); 66072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // posting reply to everyone that's waiting 6613f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar List<sp<AReplyToken>>::iterator it; 66272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang for (it = mStopReplyIDQueue.begin(); 66372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang it != mStopReplyIDQueue.end(); it++) { 66472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage)->postReply(*it); 66572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 66672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopReplyIDQueue.clear(); 66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping = false; 6686a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ++mGeneration; 66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 67072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 67172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 672764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangvoid MediaCodecSource::resume(int64_t resumeStartTimeUs) { 67372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mFlags & FLAG_USE_SURFACE_INPUT); 67472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder != NULL) { 67572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> params = new AMessage; 67672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang params->setInt32("drop-input-frames", false); 677764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang if (resumeStartTimeUs > 0) { 678764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang params->setInt64("drop-start-time-us", resumeStartTimeUs); 67972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 68072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->setParameters(params); 68172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 68272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 68372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 68472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() { 6856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar MediaBuffer* mbuf = NULL; 6866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar while (!mAvailEncoderInputIndices.empty() && mPuller->readBuffer(&mbuf)) { 68772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t bufferIndex = *mAvailEncoderInputIndices.begin(); 68872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin()); 68972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 69072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t timeUs = 0ll; 69172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang uint32_t flags = 0; 69272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size_t size = 0; 69372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 69472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf != NULL) { 69572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs)); 696a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (mFirstSampleSystemTimeUs < 0ll) { 697a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mFirstSampleSystemTimeUs = systemTime() / 1000; 698a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (mPausePending) { 699a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mPausePending = false; 700764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang onPause(mFirstSampleSystemTimeUs); 701a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mbuf->release(); 702a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mAvailEncoderInputIndices.push_back(bufferIndex); 703a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim return OK; 704a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 705a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 706a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim 707d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim timeUs += mInputBufferTimeOffsetUs; 70872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 70972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // push decoding time for video, or drift time for audio 71072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 71172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDecodingTimeQueue.push_back(timeUs); 71272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 71372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME 71472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFirstSampleTimeUs < 0ll) { 71572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mFirstSampleTimeUs = timeUs; 71672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 71772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang int64_t driftTimeUs = 0; 71872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs) 71972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang && driftTimeUs) { 72072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs; 72172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 72272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mDriftTimeQueue.push_back(driftTimeUs); 72372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME 72472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 72572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7267e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> inbuf; 7271099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf); 728e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George 729e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George if (err != OK || inbuf == NULL || inbuf->data() == NULL 730e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George || mbuf->data() == NULL || mbuf->size() == 0) { 7311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->release(); 7321099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 7331099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 7341099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 7351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 73672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang size = mbuf->size(); 73772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 7381099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan memcpy(inbuf->data(), mbuf->data(), size); 73972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 74072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mIsVideo) { 74172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // video encoder will release MediaBuffer when done 74272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // with underlying data. 743bc8f53b8c1c220d9ce01526b6e3834f14af98ed5Dongwon Kang inbuf->meta()->setObject("mediaBufferHolder", new MediaBufferHolder(mbuf)); 744bc8f53b8c1c220d9ce01526b6e3834f14af98ed5Dongwon Kang mbuf->release(); 74572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 74672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mbuf->release(); 74772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 74872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 74972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang flags = MediaCodec::BUFFER_FLAG_EOS; 75072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 75172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 75272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = mEncoder->queueInputBuffer( 75372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang bufferIndex, 0, size, timeUs, flags); 75472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 75572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 75672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 75772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 75872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 75972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 76072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 76172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 76272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 76372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) { 76472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping) { 76572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGE("Failed to start while we're stopping"); 76672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return INVALID_OPERATION; 76772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 768764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang int64_t startTimeUs; 769764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) { 770764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang startTimeUs = -1ll; 771764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang } 77272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 77372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStarted) { 77472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio"); 775a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (mPausePending) { 776a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mPausePending = false; 777a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim return OK; 778a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 7794cca134f0a775808458622490886d775c59bcc54Wonsik Kim if (mIsVideo) { 7804cca134f0a775808458622490886d775c59bcc54Wonsik Kim mEncoder->requestIDRFrame(); 7814cca134f0a775808458622490886d775c59bcc54Wonsik Kim } 78272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 783764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang resume(startTimeUs); 78472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 78572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 78672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mPuller->resume(); 78772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 78872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 78972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 79072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 79172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio"); 79272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 79372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang status_t err = OK; 79472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 79572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 796764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang if (mEncoder != NULL) { 797764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<AMessage> params = new AMessage; 798764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang params->setInt32("drop-input-frames", false); 799764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang if (startTimeUs >= 0) { 800764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang params->setInt64("skip-frames-before", startTimeUs); 801764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang } 802764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang mEncoder->setParameters(params); 80372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 80472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 80572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(mPuller != NULL); 806c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar sp<MetaData> meta = params; 807c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (mSetEncoderFormat) { 808c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar if (meta == NULL) { 809c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta = new MetaData; 810c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 811c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta->setInt32(kKeyPixelFormat, mEncoderFormat); 812c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar meta->setInt32(kKeyColorSpace, mEncoderDataSpace); 813c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar } 814c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar 8151d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector); 816c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar err = mPuller->start(meta.get(), notify); 81772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (err != OK) { 81872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return err; 81972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 82072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 82172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 82272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio"); 82372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 82472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStarted = true; 82572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang return OK; 82672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 82772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 828764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangvoid MediaCodecSource::onPause(int64_t pauseStartTimeUs) { 829764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang if ((mFlags & FLAG_USE_SURFACE_INPUT) && (mEncoder != NULL)) { 830764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<AMessage> params = new AMessage; 831764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang params->setInt32("drop-input-frames", true); 832764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang params->setInt64("drop-start-time-us", pauseStartTimeUs); 833764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang mEncoder->setParameters(params); 834a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } else { 835a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim CHECK(mPuller != NULL); 836a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mPuller->pause(); 837a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 838a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim} 839a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim 84072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) { 84172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang switch (msg->what()) { 84272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPullerNotify: 84372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 8446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar int32_t eos = 0; 8456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (msg->findInt32("eos", &eos) && eos) { 8466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("puller (%s) reached EOS", mIsVideo ? "video" : "audio"); 84716e79115e497386eaf010af388627f94314a55a3Chong Zhang signalEOS(); 8486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar break; 84972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 85072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 85172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 8526a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str()); 85372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 85472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 85572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 85672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang feedEncoderInputBuffers(); 85772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 85872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 85972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatEncoderActivity: 86072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 86172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mEncoder == NULL) { 86272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 86372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 86472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 8651099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t cbID; 8661099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("callbackID", &cbID)); 8671099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (cbID == MediaCodec::CB_INPUT_AVAILABLE) { 8681099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t index; 8691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("index", &index)); 8701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8711099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mAvailEncoderInputIndices.push_back(index); 8721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan feedEncoderInputBuffers(); 87358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } else if (cbID == MediaCodec::CB_OUTPUT_FORMAT_CHANGED) { 87458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar status_t err = mEncoder->getOutputFormat(&mOutputFormat); 87558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar if (err != OK) { 87658fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar signalEOS(err); 87758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar break; 87858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar } 879ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar sp<MetaData> meta = new MetaData; 880ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar convertMessageToMetaData(mOutputFormat, meta); 881ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar mMeta.lock().set(meta); 8821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) { 8831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t index; 8841099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan size_t offset; 8851099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan size_t size; 8861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t timeUs; 8871099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int32_t flags; 8881099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("index", &index)); 8901099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findSize("offset", &offset)); 8911099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findSize("size", &size)); 8921099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt64("timeUs", &timeUs)); 8931099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("flags", &flags)); 8941099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 8951099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (flags & MediaCodec::BUFFER_FLAG_EOS) { 8961099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mEncoder->releaseOutputBuffer(index); 8971099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 8981099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 8991099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 900f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang 9017e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim sp<MediaCodecBuffer> outbuf; 9021099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err = mEncoder->getOutputBuffer(index, &outbuf); 903e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George if (err != OK || outbuf == NULL || outbuf->data() == NULL 904e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George || outbuf->size() == 0) { 9051099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 9061099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 9071099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 908f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang 9091099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan MediaBuffer *mbuf = new MediaBuffer(outbuf->size()); 91001d1e525584d037b80d7c9ab79010fd2a5b9a870Andy Hung mbuf->setObserver(this); 911a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mbuf->add_ref(); 91272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9131099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) { 9141099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (mIsVideo) { 9151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t decodingTimeUs; 9161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (mFlags & FLAG_USE_SURFACE_INPUT) { 917a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (mFirstSampleSystemTimeUs < 0ll) { 918a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mFirstSampleSystemTimeUs = systemTime() / 1000; 919a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (mPausePending) { 920a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mPausePending = false; 921764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang onPause(mFirstSampleSystemTimeUs); 922a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mbuf->release(); 923a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim break; 924a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 925a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 92661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang // Timestamp offset is already adjusted in GraphicBufferSource. 927e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim // GraphicBufferSource is supposed to discard samples 928e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim // queued before start, and offset timeUs by start time 929e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim CHECK_GE(timeUs, 0ll); 9301099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // TODO: 9311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // Decoding time for surface source is unavailable, 9321099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // use presentation time for now. May need to move 9331099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan // this logic into MediaCodec. 9341099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan decodingTimeUs = timeUs; 9351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 9361099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(!mDecodingTimeQueue.empty()); 9371099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan decodingTimeUs = *(mDecodingTimeQueue.begin()); 9381099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mDecodingTimeQueue.erase(mDecodingTimeQueue.begin()); 9391099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 9401099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); 94172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 9421099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64, 9431099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan timeUs, timeUs / 1E6, decodingTimeUs - timeUs); 9441099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 9451099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan int64_t driftTimeUs = 0; 9461099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#if DEBUG_DRIFT_TIME 9471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(!mDriftTimeQueue.empty()); 9481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan driftTimeUs = *(mDriftTimeQueue.begin()); 9491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mDriftTimeQueue.erase(mDriftTimeQueue.begin()); 9501099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs); 9511099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#endif // DEBUG_DRIFT_TIME 9521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64, 9531099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan timeUs, timeUs / 1E6, driftTimeUs); 9541099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 9551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt64(kKeyTime, timeUs); 9561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else { 9578f889be4754d40f39c9377b055988f58f3ed64a8Hangyu Kuang mbuf->meta_data()->setInt64(kKeyTime, 0ll); 9581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true); 9591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 9601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) { 9611099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true); 9621099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 963a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim memcpy(mbuf->data(), outbuf->data(), outbuf->size()); 9641099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 9651099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan { 9666a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar Mutexed<Output>::Locked output(mOutput); 9676a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mBufferQueue.push_back(mbuf); 9686a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar output->mCond.signal(); 9691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 9701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan 9711099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mEncoder->releaseOutputBuffer(index); 9721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } else if (cbID == MediaCodec::CB_ERROR) { 9731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan status_t err; 9741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan CHECK(msg->findInt32("err", &err)); 9751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan ALOGE("Encoder (%s) reported error : 0x%x", 9761099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan mIsVideo ? "video" : "audio", err); 977c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 978c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan mStopping = true; 979c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan mPuller->stop(); 980c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan } 9811099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan signalEOS(); 9821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan } 9831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan break; 98472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 98572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStart: 98672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 9873f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 98872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 98972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 99072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<RefBase> obj; 99172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->findObject("meta", &obj)); 99272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang MetaData *params = static_cast<MetaData *>(obj.get()); 99372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 99472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang sp<AMessage> response = new AMessage; 99572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->setInt32("err", onStart(params)); 99672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang response->postReply(replyID); 99772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 99872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 99972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatStop: 100072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 100116e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio"); 100272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10033f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 100472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 100572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 10066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (mOutput.lock()->mEncoderReachedEOS) { 100772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if we already reached EOS, reply and return now 100816e79115e497386eaf010af388627f94314a55a3Chong Zhang ALOGI("encoder (%s) already stopped", 100972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mIsVideo ? "video" : "audio"); 101072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang (new AMessage)->postReply(replyID); 101172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 101272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 101372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 101472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopReplyIDQueue.push_back(replyID); 101572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mStopping) { 101672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // nothing to do if we're already stopping, reply will be posted 101772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // to all when we're stopped. 101872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 101972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 102072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 102172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mStopping = true; 102272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 1023f72cefddf378909f360998852e41f49042711299Hangyu Kuang int64_t timeoutUs = kStopTimeoutUs; 102472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang // if using surface, signal source EOS and wait for EOS to come back. 10256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // otherwise, stop puller (which also clears the input buffer queue) 10266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // and wait for the EOS message. We cannot call source->stop() because 10276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // the encoder may still be processing input buffers. 102872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 102972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang mEncoder->signalEndOfInputStream(); 1030f72cefddf378909f360998852e41f49042711299Hangyu Kuang // Increase the timeout if there is delay in the GraphicBufferSource 1031f72cefddf378909f360998852e41f49042711299Hangyu Kuang sp<AMessage> inputFormat; 1032f72cefddf378909f360998852e41f49042711299Hangyu Kuang int64_t stopTimeOffsetUs; 1033f72cefddf378909f360998852e41f49042711299Hangyu Kuang if (mEncoder->getInputFormat(&inputFormat) == OK && 1034f72cefddf378909f360998852e41f49042711299Hangyu Kuang inputFormat->findInt64("android._stop-time-offset-us", &stopTimeOffsetUs) && 1035f72cefddf378909f360998852e41f49042711299Hangyu Kuang stopTimeOffsetUs > 0) { 1036cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang if (stopTimeOffsetUs > kMaxStopTimeOffsetUs) { 1037cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang ALOGW("Source stopTimeOffsetUs %lld too large, limit at %lld us", 1038cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang (long long)stopTimeOffsetUs, (long long)kMaxStopTimeOffsetUs); 1039cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang stopTimeOffsetUs = kMaxStopTimeOffsetUs; 1040cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang } 1041f72cefddf378909f360998852e41f49042711299Hangyu Kuang timeoutUs += stopTimeOffsetUs; 1042cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang } else { 1043cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang // Use kMaxStopTimeOffsetUs if stop time offset is not provided by input source 1044cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang timeoutUs = kMaxStopTimeOffsetUs; 1045f72cefddf378909f360998852e41f49042711299Hangyu Kuang } 104672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 10476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar mPuller->stop(); 104872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 10496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 10506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar // complete stop even if encoder/puller stalled 10516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar sp<AMessage> timeoutMsg = new AMessage(kWhatStopStalled, mReflector); 10526a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar timeoutMsg->setInt32("generation", mGeneration); 1053f72cefddf378909f360998852e41f49042711299Hangyu Kuang timeoutMsg->post(timeoutUs); 105472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 105572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 10566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 10576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar case kWhatStopStalled: 10586a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar { 10596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar int32_t generation; 10606a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar CHECK(msg->findInt32("generation", &generation)); 10616a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (generation != mGeneration) { 10626a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar break; 10636a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 10646a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 10656a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar if (!(mFlags & FLAG_USE_SURFACE_INPUT)) { 10666a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("source (%s) stopping", mIsVideo ? "video" : "audio"); 106772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar mPuller->interruptSource(); 10686a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio"); 10696a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 10706a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar signalEOS(); 1071764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang break; 10726a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar } 10736a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar 107472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang case kWhatPause: 107572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang { 1076a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim if (mFirstSampleSystemTimeUs < 0) { 1077a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim mPausePending = true; 107872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } else { 1079764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<RefBase> obj; 1080764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang CHECK(msg->findObject("meta", &obj)); 1081764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang MetaData *params = static_cast<MetaData *>(obj.get()); 1082764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang int64_t pauseStartTimeUs = -1; 1083764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang if (params == NULL || !params->findInt64(kKeyTime, &pauseStartTimeUs)) { 1084764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang pauseStartTimeUs = -1ll; 1085764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang } 1086764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang onPause(pauseStartTimeUs); 108772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 108872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang break; 108972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 1090d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim case kWhatSetInputBufferTimeOffset: 1091d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim { 1092d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<AReplyToken> replyID; 1093d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim CHECK(msg->senderAwaitsResponse(&replyID)); 109461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang status_t err = OK; 1095d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs)); 1096d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim 109761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang // Propagate the timestamp offset to GraphicBufferSource. 10986d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang if (mFlags & FLAG_USE_SURFACE_INPUT) { 109961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang sp<AMessage> params = new AMessage; 110061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang params->setInt64("time-offset-us", mInputBufferTimeOffsetUs); 110161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang err = mEncoder->setParameters(params); 110261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang } 110361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang 1104d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim sp<AMessage> response = new AMessage; 110561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang response->setInt32("err", err); 1106d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim response->postReply(replyID); 1107d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim break; 1108d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim } 1109f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang case kWhatSetStopTimeUs: 1110764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang { 1111764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<AReplyToken> replyID; 1112764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang CHECK(msg->senderAwaitsResponse(&replyID)); 1113764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang status_t err = OK; 1114764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang int64_t stopTimeUs; 1115764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang CHECK(msg->findInt64("stop-time-us", &stopTimeUs)); 1116764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang 1117f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang // Propagate the stop time to GraphicBufferSource. 1118764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang if (mFlags & FLAG_USE_SURFACE_INPUT) { 1119764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<AMessage> params = new AMessage; 1120764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang params->setInt64("stop-time-us", stopTimeUs); 1121764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang err = mEncoder->setParameters(params); 1122f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang } else { 1123f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang err = mPuller->setStopTimeUs(stopTimeUs); 1124764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang } 1125764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang 1126764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang sp<AMessage> response = new AMessage; 1127764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang response->setInt32("err", err); 1128764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang response->postReply(replyID); 1129764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang break; 1130764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang } 1131a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim case kWhatGetFirstSampleSystemTimeUs: 1132a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim { 1133a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim sp<AReplyToken> replyID; 1134a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim CHECK(msg->senderAwaitsResponse(&replyID)); 1135a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim 1136a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim sp<AMessage> response = new AMessage; 1137a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim response->setInt64("time-us", mFirstSampleSystemTimeUs); 1138a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim response->postReply(replyID); 1139a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim break; 1140a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim } 114172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang default: 114272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang TRESPASS(); 114372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang } 114472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} 114572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang 114672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android 1147