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>
267e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.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>
3872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/Utils.h>
3972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangnamespace android {
4172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarconst int32_t kDefaultSwVideoEncoderFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
43b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnarconst int32_t kDefaultHwVideoEncoderFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
442cbf6cea23539bfe99e36d1d221de62255452e86Eino-Ville Talvalaconst int32_t kDefaultVideoEncoderDataSpace = HAL_DATASPACE_V0_BT709;
45c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarconst int kStopTimeoutUs = 300000; // allow 1 sec for shutting down encoder
47cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang// allow maximum 1 sec for stop time offset. This limits the the delay in the
48cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang// input source.
49cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuangconst int kMaxStopTimeOffsetUs = 1000000;
506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
5172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource::Puller : public AHandler {
52090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit Puller(const sp<MediaSource> &source);
5372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5472e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    void interruptSource();
5572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t start(const sp<MetaData> &meta, const sp<AMessage> &notify);
5616e79115e497386eaf010af388627f94314a55a3Chong Zhang    void stop();
576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    void stopSource();
5872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void pause();
5972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void resume();
60f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    status_t setStopTimeUs(int64_t stopTimeUs);
616a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool readBuffer(MediaBuffer **buffer);
626a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
6372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected:
6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual void onMessageReceived(const sp<AMessage> &msg);
6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual ~Puller();
6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate:
6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    enum {
6972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStart = 'msta',
7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStop,
7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatPull,
72f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        kWhatSetStopTimeUs,
7372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    };
7472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaSource> mSource;
7672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> mNotify;
7772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<ALooper> mLooper;
7872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mIsAudio;
796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    struct Queue {
816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Queue()
826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            : mReadPendingSince(0),
836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar              mPaused(false),
846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar              mPulling(false) { }
856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int64_t mReadPendingSince;
866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mPaused;
876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mPulling;
886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Vector<MediaBuffer *> mReadBuffers;
896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        void flush();
916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // if queue is empty, return false and set *|buffer| to NULL . Otherwise, pop
9272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        // buffer from front of the queue, place it into *|buffer| and return true.
936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool readBuffer(MediaBuffer **buffer);
9472e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        // add a buffer to the back of the queue
956a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        void pushBuffer(MediaBuffer *mbuf);
966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    };
976a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue> mQueue;
9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void schedulePull();
10172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void handleEOS();
10272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(Puller);
10472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang};
10572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10672cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source)
10772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mSource(source),
10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mLooper(new ALooper()),
1096a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mIsAudio(false)
1106a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar{
11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MetaData> meta = source->getFormat();
11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    const char *mime;
11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(meta->findCString(kKeyMIMEType, &mime));
11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mIsAudio = !strncasecmp(mime, "audio/", 6);
11672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->setName("pull_looper");
11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
12072cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() {
12172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(id());
12272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->stop();
12372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
12472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::pushBuffer(MediaBuffer *mbuf) {
1266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    mReadBuffers.push_back(mbuf);
1276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::Queue::readBuffer(MediaBuffer **mbuf) {
1306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (mReadBuffers.empty()) {
1316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        *mbuf = NULL;
1326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        return false;
1336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    *mbuf = *mReadBuffers.begin();
1356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    mReadBuffers.erase(mReadBuffers.begin());
1366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return true;
1376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::flush() {
1406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    MediaBuffer *mbuf;
1416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (readBuffer(&mbuf)) {
1426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // there are no null buffers in the queue
1436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mbuf->release();
1446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::readBuffer(MediaBuffer **mbuf) {
1486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
1496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return queue->readBuffer(mbuf);
1506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
15272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError(
15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
15472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
15872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
16372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
168f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuangstatus_t MediaCodecSource::Puller::setStopTimeUs(int64_t stopTimeUs) {
169f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, this);
170f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    msg->setInt64("stop-time-us", stopTimeUs);
171f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    return postSynchronouslyAndReturnError(msg);
172f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang}
173f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang
1746a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> &notify) {
17572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGV("puller (%s) start", mIsAudio ? "audio" : "video");
17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->start(
17772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* runOnCallingThread */,
17872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* canCallJava */,
17972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            PRIORITY_AUDIO);
18072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(this);
18172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mNotify = notify;
18272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
18472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", meta);
18572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
18672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
18772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
18816e79115e497386eaf010af388627f94314a55a3Chong Zhangvoid MediaCodecSource::Puller::stop() {
1896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool interrupt = false;
1906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
1916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // mark stopping before actually reaching kWhatStop on the looper, so the pulling will
1926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // stop.
1936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Queue>::Locked queue(mQueue);
1946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        queue->mPulling = false;
1956a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        interrupt = queue->mReadPendingSince && (queue->mReadPendingSince < ALooper::GetNowUs() - 1000000);
1966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        queue->flush(); // flush any unprocessed pulled buffers
1976a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
19816e79115e497386eaf010af388627f94314a55a3Chong Zhang
1996a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (interrupt) {
20072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        interruptSource();
2016a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
2026a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
20316e79115e497386eaf010af388627f94314a55a3Chong Zhang
20472e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnarvoid MediaCodecSource::Puller::interruptSource() {
20572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    // call source->stop if read has been pending for over a second
20672e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    // We have to call this outside the looper as looper is pending on the read.
20772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    mSource->stop();
20872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar}
20972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
2106a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::stopSource() {
21172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
21272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    (void)postSynchronouslyAndReturnError(msg);
21372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
21472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() {
2166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
2176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    queue->mPaused = true;
21872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
21972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() {
2216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
2226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    queue->mPaused = false;
22372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
22472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() {
2266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    (new AMessage(kWhatPull, this))->post();
22772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
22872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() {
2306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video");
2316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    sp<AMessage> msg = mNotify->dup();
2326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    msg->setInt32("eos", 1);
2336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    msg->post();
23472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
23572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
23672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
23772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStart:
23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
24072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<RefBase> obj;
24172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->findObject("meta", &obj));
24272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            {
2446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                Mutexed<Queue>::Locked queue(mQueue);
2456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                queue->mPulling = true;
2466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
24772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
24872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->start(static_cast<MetaData *>(obj.get()));
24972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (err == OK) {
25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                schedulePull();
25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
25472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<AMessage> response = new AMessage;
25572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->setInt32("err", err);
25672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2573f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
25872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
25972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->postReply(replyID);
26072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
26172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
26272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
263f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        case kWhatSetStopTimeUs:
264f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        {
265f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            sp<AReplyToken> replyID;
266f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            CHECK(msg->senderAwaitsResponse(&replyID));
267f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            int64_t stopTimeUs;
268f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            CHECK(msg->findInt64("stop-time-us", &stopTimeUs));
269f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            status_t err = mSource->setStopTimeUs(stopTimeUs);
270f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang
271f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            sp<AMessage> response = new AMessage;
272f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            response->setInt32("err", err);
273f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            response->postReply(replyID);
274f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            break;
275f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        }
276f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang
27772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStop:
27872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
2796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mSource->stop();
28072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
28172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            sp<AMessage> response = new AMessage;
28272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            response->setInt32("err", OK);
28372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
28472e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            sp<AReplyToken> replyID;
28572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
28672e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            response->postReply(replyID);
28772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
28872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
28972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
29072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatPull:
29172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
2926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            Mutexed<Queue>::Locked queue(mQueue);
2936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue->mReadPendingSince = ALooper::GetNowUs();
2946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (!queue->mPulling) {
2956a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                handleEOS();
29672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                break;
29772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
29872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2996a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.unlock();
3006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            MediaBuffer *mbuf = NULL;
30172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->read(&mbuf);
3026a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.lock();
30372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3046a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue->mReadPendingSince = 0;
3056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            // if we need to discard buffer
3066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (!queue->mPulling || queue->mPaused || err != OK) {
3076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                if (mbuf != NULL) {
30872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf->release();
30972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf = NULL;
31072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
3116a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                if (queue->mPulling && err == OK) {
3126a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                    msg->post(); // if simply paused, keep pulling source
3136d6c21b8d2ed66007833dae0451b0a211c97e592Wonsik Kim                    break;
3146a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                } else if (err == ERROR_END_OF_STREAM) {
31572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGV("stream ended, mbuf %p", mbuf);
3166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                } else if (err != OK) {
31772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGE("error %d reading stream.", err);
31872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
3196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
32072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (mbuf != NULL) {
3226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                queue->pushBuffer(mbuf);
32372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
32472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.unlock();
32672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (mbuf != NULL) {
3286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                mNotify->post();
3296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                msg->post();
3306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            } else {
3316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                handleEOS();
3326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
33372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
33672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        default:
33772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            TRESPASS();
33872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
33972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
34072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos MolnarMediaCodecSource::Output::Output()
3426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    : mEncoderReachedEOS(false),
3436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mErrorCode(OK) {
3446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
3456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
34672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static
34772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create(
34872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &format,
35072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
351addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        const sp<PersistentSurface> &persistentSurface,
35272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags) {
353addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<MediaCodecSource> mediaSource = new MediaCodecSource(
354addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            looper, format, source, persistentSurface, flags);
35572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
35672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mediaSource->init() == OK) {
35772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return mediaSource;
35872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
35972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return NULL;
36072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
36172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
36261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuangstatus_t MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
363d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector);
364d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    msg->setInt64("time-offset-us", timeOffsetUs);
36561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    return postSynchronouslyAndReturnError(msg);
366d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim}
367d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
368a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kimint64_t MediaCodecSource::getFirstSampleSystemTimeUs() {
369a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    sp<AMessage> msg = new AMessage(kWhatGetFirstSampleSystemTimeUs, mReflector);
370a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    sp<AMessage> response;
371a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    msg->postAndAwaitResponse(&response);
372a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    int64_t timeUs;
373a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    if (!response->findInt64("time-us", &timeUs)) {
374a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        timeUs = -1ll;
375a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    }
376a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    return timeUs;
377a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim}
378a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim
37972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) {
3801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, mReflector);
38172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", params);
38272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
38372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
38472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
38572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() {
3861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, mReflector);
3876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return postSynchronouslyAndReturnError(msg);
38872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
38972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
390764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
391f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuangstatus_t MediaCodecSource::setStopTimeUs(int64_t stopTimeUs) {
392f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, mReflector);
393764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    msg->setInt64("stop-time-us", stopTimeUs);
394764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    return postSynchronouslyAndReturnError(msg);
395764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang}
396764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
397764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangstatus_t MediaCodecSource::pause(MetaData* params) {
398764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    sp<AMessage> msg = new AMessage(kWhatPause, mReflector);
399764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    msg->setObject("meta", params);
400764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    msg->post();
40172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
40272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
40372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
404ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnarsp<MetaData> MediaCodecSource::getFormat() {
405ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    Mutexed<sp<MetaData>>::Locked meta(mMeta);
406ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    return *meta;
407ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar}
408ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar
40972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() {
41072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
41172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return mGraphicBufferProducer;
41272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
41372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaCodecSource::read(
41584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        MediaBuffer** buffer, const ReadOptions* /* options */) {
4166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Output>::Locked output(mOutput);
41772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    *buffer = NULL;
4196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (output->mBufferQueue.size() == 0 && !output->mEncoderReachedEOS) {
4206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output.waitForCondition(output->mCond);
42172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
4226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (!output->mEncoderReachedEOS) {
4236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        *buffer = *output->mBufferQueue.begin();
4246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mBufferQueue.erase(output->mBufferQueue.begin());
42572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
42672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
4276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return output->mErrorCode;
42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) {
43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->setObserver(0);
43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->release();
43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43572cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource(
43672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &outputFormat,
43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
439addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        const sp<PersistentSurface> &persistentSurface,
44072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags)
44172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mLooper(looper),
44272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mOutputFormat(outputFormat),
44372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mMeta(new MetaData),
44472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFlags(flags),
44572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mIsVideo(false),
44672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStarted(false),
44772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStopping(false),
44872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mDoMoreWorkPending(false),
449c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mSetEncoderFormat(false),
450c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderFormat(0),
451c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderDataSpace(0),
452addf2cbb120346ae42e78fa739245a353db5edadChong Zhang      mPersistentSurface(persistentSurface),
453d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim      mInputBufferTimeOffsetUs(0),
454a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim      mFirstSampleSystemTimeUs(-1ll),
455a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim      mPausePending(false),
45672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFirstSampleTimeUs(-1ll),
4576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mGeneration(0) {
45872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mLooper != NULL);
45972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString mime;
46172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &mime));
46272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!strncasecmp("video/", mime.c_str(), 6)) {
46472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mIsVideo = true;
46572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
46672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
46872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mPuller = new Puller(source);
46972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
47072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
47172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47272cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() {
47372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    releaseEncoder();
47472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->stop();
47672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(mReflector->id());
47772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
47872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() {
48072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = initEncoder();
48172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
48372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        releaseEncoder();
48472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
48572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
48772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
48872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() {
49072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mReflector = new AHandlerReflector<MediaCodecSource>(this);
49172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(mReflector);
49272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper = new ALooper;
49472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->setName("codec_looper");
49572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->start();
49672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
49872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputFormat->setInt32("create-input-buffers-suspended", 1);
49972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
50072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
50172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString outputMIME;
50272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &outputMIME));
50372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
50416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    Vector<AString> matchingCodecs;
50516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    MediaCodecList::findMatchingCodecs(
50616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            outputMIME.c_str(), true /* encoder */,
50716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            ((mFlags & FLAG_PREFER_SOFTWARE_CODEC) ? MediaCodecList::kPreferSoftwareCodecs : 0),
50816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            &matchingCodecs);
50972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
51016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    status_t err = NO_INIT;
51116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    for (size_t ix = 0; ix < matchingCodecs.size(); ++ix) {
51216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = MediaCodec::CreateByComponentName(
51316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                mCodecLooper, matchingCodecs[ix]);
51416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
51516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (mEncoder == NULL) {
51616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            continue;
51716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
51816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
51916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
52072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector);
52216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->setCallback(mEncoderActivityNotify);
52372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        err = mEncoder->configure(
52516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    mOutputFormat,
52616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* nativeWindow */,
52716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* crypto */,
52816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    MediaCodec::CONFIGURE_FLAG_ENCODE);
529421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
53016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (err == OK) {
53116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            break;
53216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
53316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->release();
53416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = NULL;
53516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    }
53672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
53772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
53872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
53972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
54072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
54172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->getOutputFormat(&mOutputFormat);
542ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    sp<MetaData> meta = new MetaData;
543ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    convertMessageToMetaData(mOutputFormat, meta);
544ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    mMeta.lock().set(meta);
54572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
54672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
54772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mIsVideo);
54872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
549addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        if (mPersistentSurface != NULL) {
550e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // When using persistent surface, we are only interested in the
551e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // consumer, but have to use PersistentSurface as a wrapper to
552e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // pass consumer over messages (similar to BufferProducerWrapper)
553addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            err = mEncoder->setInputSurface(mPersistentSurface);
554e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        } else {
555e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            err = mEncoder->createInputSurface(&mGraphicBufferProducer);
556e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        }
55772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
55872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
55972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
56072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
56172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
56272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
563c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    sp<AMessage> inputFormat;
564c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    int32_t usingSwReadOften;
565c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    mSetEncoderFormat = false;
566b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mEncoder->getInputFormat(&inputFormat) == OK) {
567c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mSetEncoderFormat = true;
568b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (inputFormat->findInt32("using-sw-read-often", &usingSwReadOften)
569b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && usingSwReadOften) {
570b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // this is a SW encoder; signal source to allocate SW readable buffers
571b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mEncoderFormat = kDefaultSwVideoEncoderFormat;
572b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else {
573b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mEncoderFormat = kDefaultHwVideoEncoderFormat;
574b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (!inputFormat->findInt32("android._dataspace", &mEncoderDataSpace)) {
576b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mEncoderDataSpace = kDefaultVideoEncoderDataSpace;
577b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
578b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("setting dataspace %#x, format %#x", mEncoderDataSpace, mEncoderFormat);
579c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
580c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
5811099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan    err = mEncoder->start();
58272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
58372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
58472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
58572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
58672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
5886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Output>::Locked output(mOutput);
5896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mEncoderReachedEOS = false;
5906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mErrorCode = OK;
5916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
59272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
59372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
59472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
59572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
59672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() {
59772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder == NULL) {
59872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return;
59972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
60072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
60172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->release();
60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder.clear();
60372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
60472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
60572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError(
60672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
60772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
60872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
60972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
61572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
61672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
61772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
61972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
62072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
62172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) {
6226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool reachedEOS = false;
6236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
6246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Output>::Locked output(mOutput);
6256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        reachedEOS = output->mEncoderReachedEOS;
6266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (!reachedEOS) {
6276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("encoder (%s) reached EOS", mIsVideo ? "video" : "audio");
62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // release all unread media buffers
6296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            for (List<MediaBuffer*>::iterator it = output->mBufferQueue.begin();
6306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                    it != output->mBufferQueue.end(); it++) {
63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                (*it)->release();
63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
6336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mBufferQueue.clear();
6346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mEncoderReachedEOS = true;
6356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mErrorCode = err;
6366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mCond.signal();
6376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
6386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            reachedEOS = true;
6396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output.unlock();
6406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            releaseEncoder();
64172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
64272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
6436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
6446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (mStopping && reachedEOS) {
64516e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio");
6466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mPuller->stopSource();
6476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
64872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // posting reply to everyone that's waiting
6493f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        List<sp<AReplyToken>>::iterator it;
65072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        for (it = mStopReplyIDQueue.begin();
65172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                it != mStopReplyIDQueue.end(); it++) {
65272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(*it);
65372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
65472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.clear();
65572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = false;
6566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        ++mGeneration;
65772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
65872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
65972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
660764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangvoid MediaCodecSource::resume(int64_t resumeStartTimeUs) {
66172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
66272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder != NULL) {
66372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> params = new AMessage;
66472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        params->setInt32("drop-input-frames", false);
665764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (resumeStartTimeUs > 0) {
666764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            params->setInt64("drop-start-time-us", resumeStartTimeUs);
66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
66872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mEncoder->setParameters(params);
66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
67072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
67172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
67272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() {
6736a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    MediaBuffer* mbuf = NULL;
6746a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (!mAvailEncoderInputIndices.empty() && mPuller->readBuffer(&mbuf)) {
67572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
67672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
67772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
67872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        int64_t timeUs = 0ll;
67972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags = 0;
68072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t size = 0;
68172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
68272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mbuf != NULL) {
68372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
684a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            if (mFirstSampleSystemTimeUs < 0ll) {
685a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                mFirstSampleSystemTimeUs = systemTime() / 1000;
686a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                if (mPausePending) {
687a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                    mPausePending = false;
688764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    onPause(mFirstSampleSystemTimeUs);
689a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                    mbuf->release();
690a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                    mAvailEncoderInputIndices.push_back(bufferIndex);
691a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                    return OK;
692a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                }
693a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            }
694a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim
695d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim            timeUs += mInputBufferTimeOffsetUs;
69672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // push decoding time for video, or drift time for audio
69872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
69972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDecodingTimeQueue.push_back(timeUs);
70072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
70172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME
70272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mFirstSampleTimeUs < 0ll) {
70372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mFirstSampleTimeUs = timeUs;
70472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
70572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                int64_t driftTimeUs = 0;
70672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs)
70772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                        && driftTimeUs) {
70872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs;
70972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
71072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDriftTimeQueue.push_back(driftTimeUs);
71172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME
71272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
71372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7147e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            sp<MediaCodecBuffer> inbuf;
7151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf);
716e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George
717e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George            if (err != OK || inbuf == NULL || inbuf->data() == NULL
718e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George                    || mbuf->data() == NULL || mbuf->size() == 0) {
7191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->release();
7201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
7211099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
7221099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
7231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
72472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            size = mbuf->size();
72572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7261099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            memcpy(inbuf->data(), mbuf->data(), size);
72772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
72872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
72972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // video encoder will release MediaBuffer when done
73072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // with underlying data.
7311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                inbuf->setMediaBufferBase(mbuf);
73272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
73372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mbuf->release();
73472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
73572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
73672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            flags = MediaCodec::BUFFER_FLAG_EOS;
73772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
73872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
73972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err = mEncoder->queueInputBuffer(
74072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                bufferIndex, 0, size, timeUs, flags);
74172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
74272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
74372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
74472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
74572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
74672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
74772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
74872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
74972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
75072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) {
75172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStopping) {
75272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGE("Failed to start while we're stopping");
75372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return INVALID_OPERATION;
75472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
755764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    int64_t startTimeUs;
756764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
757764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        startTimeUs = -1ll;
758764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
75972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
76072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStarted) {
76172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio");
762a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        if (mPausePending) {
763a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            mPausePending = false;
764a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            return OK;
765a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        }
7664cca134f0a775808458622490886d775c59bcc54Wonsik Kim        if (mIsVideo) {
7674cca134f0a775808458622490886d775c59bcc54Wonsik Kim            mEncoder->requestIDRFrame();
7684cca134f0a775808458622490886d775c59bcc54Wonsik Kim        }
76972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
770764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            resume(startTimeUs);
77172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
77272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mPuller != NULL);
77372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPuller->resume();
77472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
77572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
77672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
77772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
77872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio");
77972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
78072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = OK;
78172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
78272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
783764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (mEncoder != NULL) {
784764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            sp<AMessage> params = new AMessage;
785764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            params->setInt32("drop-input-frames", false);
786764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            if (startTimeUs >= 0) {
787764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                params->setInt64("skip-frames-before", startTimeUs);
788764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
789764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            mEncoder->setParameters(params);
79072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
79172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    } else {
79272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mPuller != NULL);
793c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        sp<MetaData> meta = params;
794c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mSetEncoderFormat) {
795c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            if (meta == NULL) {
796c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                meta = new MetaData;
797c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            }
798c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyPixelFormat, mEncoderFormat);
799c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyColorSpace, mEncoderDataSpace);
800c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
801c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
8021d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector);
803c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        err = mPuller->start(meta.get(), notify);
80472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
80572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
80672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
80772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
80872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
80972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio");
81072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
81172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mStarted = true;
81272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
81372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
81472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
815764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangvoid MediaCodecSource::onPause(int64_t pauseStartTimeUs) {
816764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if ((mFlags & FLAG_USE_SURFACE_INPUT) && (mEncoder != NULL)) {
817764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        sp<AMessage> params = new AMessage;
818764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        params->setInt32("drop-input-frames", true);
819764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        params->setInt64("drop-start-time-us", pauseStartTimeUs);
820764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mEncoder->setParameters(params);
821a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    } else {
822a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        CHECK(mPuller != NULL);
823a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        mPuller->pause();
824a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    }
825a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim}
826a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim
82772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
82872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
82972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPullerNotify:
83072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
8316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int32_t eos = 0;
8326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (msg->findInt32("eos", &eos) && eos) {
8336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("puller (%s) reached EOS", mIsVideo ? "video" : "audio");
83416e79115e497386eaf010af388627f94314a55a3Chong Zhang            signalEOS();
8356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            break;
83672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
83772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
83872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
8396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str());
84072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
84172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
84272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
84372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        feedEncoderInputBuffers();
84472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
84572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
84672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatEncoderActivity:
84772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
84872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
84972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
85072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
85172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        int32_t cbID;
8531099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        CHECK(msg->findInt32("callbackID", &cbID));
8541099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        if (cbID == MediaCodec::CB_INPUT_AVAILABLE) {
8551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
8561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
8571099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mAvailEncoderInputIndices.push_back(index);
8591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            feedEncoderInputBuffers();
86058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        } else if (cbID == MediaCodec::CB_OUTPUT_FORMAT_CHANGED) {
86158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            status_t err = mEncoder->getOutputFormat(&mOutputFormat);
86258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            if (err != OK) {
86358fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                signalEOS(err);
86458fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                break;
86558fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            }
866ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar            sp<MetaData> meta = new MetaData;
867ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar            convertMessageToMetaData(mOutputFormat, meta);
868ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar            mMeta.lock().set(meta);
8691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) {
8701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
8711099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t offset;
8721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t size;
8731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int64_t timeUs;
8741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t flags;
8751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8761099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
8771099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("offset", &offset));
8781099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("size", &size));
8791099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt64("timeUs", &timeUs));
8801099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("flags", &flags));
8811099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_EOS) {
8831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mEncoder->releaseOutputBuffer(index);
8841099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
8851099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
8861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
887f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
8887e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            sp<MediaCodecBuffer> outbuf;
8891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getOutputBuffer(index, &outbuf);
890e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George            if (err != OK || outbuf == NULL || outbuf->data() == NULL
891e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George                || outbuf->size() == 0) {
8921099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
8931099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
8941099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
895f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
8961099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            MediaBuffer *mbuf = new MediaBuffer(outbuf->size());
89701d1e525584d037b80d7c9ab79010fd2a5b9a870Andy Hung            mbuf->setObserver(this);
898a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            mbuf->add_ref();
89972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9001099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) {
9011099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                if (mIsVideo) {
9021099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t decodingTimeUs;
9031099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    if (mFlags & FLAG_USE_SURFACE_INPUT) {
904a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                        if (mFirstSampleSystemTimeUs < 0ll) {
905a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                            mFirstSampleSystemTimeUs = systemTime() / 1000;
906a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                            if (mPausePending) {
907a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                                mPausePending = false;
908764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                                onPause(mFirstSampleSystemTimeUs);
909a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                                mbuf->release();
910a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                                break;
911a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                            }
912a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                        }
91361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                        // Timestamp offset is already adjusted in GraphicBufferSource.
914e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim                        // GraphicBufferSource is supposed to discard samples
915e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim                        // queued before start, and offset timeUs by start time
916e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim                        CHECK_GE(timeUs, 0ll);
9171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // TODO:
9181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // Decoding time for surface source is unavailable,
9191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // use presentation time for now. May need to move
9201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // this logic into MediaCodec.
9211099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = timeUs;
9221099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    } else {
9231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        CHECK(!mDecodingTimeQueue.empty());
9241099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = *(mDecodingTimeQueue.begin());
9251099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        mDecodingTimeQueue.erase(mDecodingTimeQueue.begin());
9261099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    }
9271099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
92872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9291099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64,
9301099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, decodingTimeUs - timeUs);
9311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                } else {
9321099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t driftTimeUs = 0;
9331099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#if DEBUG_DRIFT_TIME
9341099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    CHECK(!mDriftTimeQueue.empty());
9351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    driftTimeUs = *(mDriftTimeQueue.begin());
9361099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mDriftTimeQueue.erase(mDriftTimeQueue.begin());
9371099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs);
9381099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#endif // DEBUG_DRIFT_TIME
9391099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64,
9401099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, driftTimeUs);
9411099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                }
9421099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt64(kKeyTime, timeUs);
9431099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            } else {
9448f889be4754d40f39c9377b055988f58f3ed64a8Hangyu Kuang                mbuf->meta_data()->setInt64(kKeyTime, 0ll);
9451099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true);
9461099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
9471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
9481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true);
9491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
950a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            memcpy(mbuf->data(), outbuf->data(), outbuf->size());
9511099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
9521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            {
9536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                Mutexed<Output>::Locked output(mOutput);
9546a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                output->mBufferQueue.push_back(mbuf);
9556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                output->mCond.signal();
9561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
9571099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
9581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mEncoder->releaseOutputBuffer(index);
9591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       } else if (cbID == MediaCodec::CB_ERROR) {
9601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err;
9611099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("err", &err));
9621099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            ALOGE("Encoder (%s) reported error : 0x%x",
9631099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mIsVideo ? "video" : "audio", err);
964c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan            if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
965c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan                mStopping = true;
966c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan                mPuller->stop();
967c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan            }
9681099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            signalEOS();
9691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       }
9701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       break;
97172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
97272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStart:
97372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
9743f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
97572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
97672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
97772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<RefBase> obj;
97872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->findObject("meta", &obj));
97972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        MetaData *params = static_cast<MetaData *>(obj.get());
98072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
98172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> response = new AMessage;
98272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->setInt32("err", onStart(params));
98372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->postReply(replyID);
98472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
98572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
98672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStop:
98772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
98816e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio");
98972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9903f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
99172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
99272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (mOutput.lock()->mEncoderReachedEOS) {
99472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // if we already reached EOS, reply and return now
99516e79115e497386eaf010af388627f94314a55a3Chong Zhang            ALOGI("encoder (%s) already stopped",
99672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mIsVideo ? "video" : "audio");
99772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(replyID);
99872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
99972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
100072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
100172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.push_back(replyID);
100272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mStopping) {
100372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // nothing to do if we're already stopping, reply will be posted
100472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // to all when we're stopped.
100572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
100672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
100772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
100872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = true;
100972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1010f72cefddf378909f360998852e41f49042711299Hangyu Kuang        int64_t timeoutUs = kStopTimeoutUs;
101172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // if using surface, signal source EOS and wait for EOS to come back.
10126a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // otherwise, stop puller (which also clears the input buffer queue)
10136a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // and wait for the EOS message. We cannot call source->stop() because
10146a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // the encoder may still be processing input buffers.
101572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
101672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mEncoder->signalEndOfInputStream();
1017f72cefddf378909f360998852e41f49042711299Hangyu Kuang            // Increase the timeout if there is delay in the GraphicBufferSource
1018f72cefddf378909f360998852e41f49042711299Hangyu Kuang            sp<AMessage> inputFormat;
1019f72cefddf378909f360998852e41f49042711299Hangyu Kuang            int64_t stopTimeOffsetUs;
1020f72cefddf378909f360998852e41f49042711299Hangyu Kuang            if (mEncoder->getInputFormat(&inputFormat) == OK &&
1021f72cefddf378909f360998852e41f49042711299Hangyu Kuang                    inputFormat->findInt64("android._stop-time-offset-us", &stopTimeOffsetUs) &&
1022f72cefddf378909f360998852e41f49042711299Hangyu Kuang                    stopTimeOffsetUs > 0) {
1023cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang                if (stopTimeOffsetUs > kMaxStopTimeOffsetUs) {
1024cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang                    ALOGW("Source stopTimeOffsetUs %lld too large, limit at %lld us",
1025cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang                        (long long)stopTimeOffsetUs, (long long)kMaxStopTimeOffsetUs);
1026cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang                    stopTimeOffsetUs = kMaxStopTimeOffsetUs;
1027cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang                }
1028f72cefddf378909f360998852e41f49042711299Hangyu Kuang                timeoutUs += stopTimeOffsetUs;
1029cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang            } else {
1030cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang                // Use kMaxStopTimeOffsetUs if stop time offset is not provided by input source
1031cf3205fab08adfdc9d5c0fef1cef54cab0074117Hangyu Kuang                timeoutUs = kMaxStopTimeOffsetUs;
1032f72cefddf378909f360998852e41f49042711299Hangyu Kuang            }
103372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
10346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mPuller->stop();
103572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
10366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
10376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // complete stop even if encoder/puller stalled
10386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        sp<AMessage> timeoutMsg = new AMessage(kWhatStopStalled, mReflector);
10396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        timeoutMsg->setInt32("generation", mGeneration);
1040f72cefddf378909f360998852e41f49042711299Hangyu Kuang        timeoutMsg->post(timeoutUs);
104172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
104272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
10436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
10446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    case kWhatStopStalled:
10456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
10466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int32_t generation;
10476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        CHECK(msg->findInt32("generation", &generation));
10486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (generation != mGeneration) {
10496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar             break;
10506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        }
10516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
10526a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
10536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("source (%s) stopping", mIsVideo ? "video" : "audio");
105472e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            mPuller->interruptSource();
10556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
10566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        }
10576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        signalEOS();
1058764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        break;
10596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
10606a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
106172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPause:
106272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
1063a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        if (mFirstSampleSystemTimeUs < 0) {
1064a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            mPausePending = true;
106572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
1066764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            sp<RefBase> obj;
1067764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            CHECK(msg->findObject("meta", &obj));
1068764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            MetaData *params = static_cast<MetaData *>(obj.get());
1069764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            int64_t pauseStartTimeUs = -1;
1070764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            if (params == NULL || !params->findInt64(kKeyTime, &pauseStartTimeUs)) {
1071764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                pauseStartTimeUs = -1ll;
1072764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
1073764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            onPause(pauseStartTimeUs);
107472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
107572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
107672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
1077d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    case kWhatSetInputBufferTimeOffset:
1078d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    {
1079d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AReplyToken> replyID;
1080d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->senderAwaitsResponse(&replyID));
108161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        status_t err = OK;
1082d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs));
1083d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
108461fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        // Propagate the timestamp offset to GraphicBufferSource.
10856d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
108661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            sp<AMessage> params = new AMessage;
108761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            params->setInt64("time-offset-us", mInputBufferTimeOffsetUs);
108861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            err = mEncoder->setParameters(params);
108961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
109061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
1091d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AMessage> response = new AMessage;
109261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        response->setInt32("err", err);
1093d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        response->postReply(replyID);
1094d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        break;
1095d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    }
1096f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    case kWhatSetStopTimeUs:
1097764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    {
1098764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        sp<AReplyToken> replyID;
1099764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        CHECK(msg->senderAwaitsResponse(&replyID));
1100764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        status_t err = OK;
1101764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        int64_t stopTimeUs;
1102764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        CHECK(msg->findInt64("stop-time-us", &stopTimeUs));
1103764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1104f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        // Propagate the stop time to GraphicBufferSource.
1105764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
1106764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            sp<AMessage> params = new AMessage;
1107764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            params->setInt64("stop-time-us", stopTimeUs);
1108764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            err = mEncoder->setParameters(params);
1109f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        } else {
1110f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            err = mPuller->setStopTimeUs(stopTimeUs);
1111764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
1112764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1113764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        sp<AMessage> response = new AMessage;
1114764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        response->setInt32("err", err);
1115764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        response->postReply(replyID);
1116764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        break;
1117764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
1118a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    case kWhatGetFirstSampleSystemTimeUs:
1119a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    {
1120a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        sp<AReplyToken> replyID;
1121a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        CHECK(msg->senderAwaitsResponse(&replyID));
1122a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim
1123a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        sp<AMessage> response = new AMessage;
1124a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        response->setInt64("time-us", mFirstSampleSystemTimeUs);
1125a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        response->postReply(replyID);
1126a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        break;
1127a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    }
112872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    default:
112972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        TRESPASS();
113072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
113172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
113272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
113372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android
1134