MediaCodecSource.cpp revision f72cefddf378909f360998852e41f49042711299
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
476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
4872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource::Puller : public AHandler {
49090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit Puller(const sp<MediaSource> &source);
5072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    void interruptSource();
5272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t start(const sp<MetaData> &meta, const sp<AMessage> &notify);
5316e79115e497386eaf010af388627f94314a55a3Chong Zhang    void stop();
546a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    void stopSource();
5572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void pause();
5672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void resume();
57f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    status_t setStopTimeUs(int64_t stopTimeUs);
586a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool readBuffer(MediaBuffer **buffer);
596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
6072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected:
6172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual void onMessageReceived(const sp<AMessage> &msg);
6272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual ~Puller();
6372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate:
6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    enum {
6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStart = 'msta',
6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStop,
6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatPull,
69f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        kWhatSetStopTimeUs,
7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    };
7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaSource> mSource;
7372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> mNotify;
7472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<ALooper> mLooper;
7572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mIsAudio;
766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
776a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    struct Queue {
786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Queue()
796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            : mReadPendingSince(0),
806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar              mPaused(false),
816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar              mPulling(false) { }
826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int64_t mReadPendingSince;
836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mPaused;
846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mPulling;
856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Vector<MediaBuffer *> mReadBuffers;
866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        void flush();
886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // if queue is empty, return false and set *|buffer| to NULL . Otherwise, pop
8972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        // buffer from front of the queue, place it into *|buffer| and return true.
906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool readBuffer(MediaBuffer **buffer);
9172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        // add a buffer to the back of the queue
926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        void pushBuffer(MediaBuffer *mbuf);
936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    };
946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue> mQueue;
9572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
9772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void schedulePull();
9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void handleEOS();
9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(Puller);
10172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang};
10272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10372cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source)
10472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mSource(source),
10572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mLooper(new ALooper()),
1066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mIsAudio(false)
1076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar{
10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MetaData> meta = source->getFormat();
10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    const char *mime;
11072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(meta->findCString(kKeyMIMEType, &mime));
11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mIsAudio = !strncasecmp(mime, "audio/", 6);
11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->setName("pull_looper");
11572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
11672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11772cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() {
11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(id());
11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->stop();
12072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
12172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::pushBuffer(MediaBuffer *mbuf) {
1236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    mReadBuffers.push_back(mbuf);
1246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::Queue::readBuffer(MediaBuffer **mbuf) {
1276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (mReadBuffers.empty()) {
1286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        *mbuf = NULL;
1296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        return false;
1306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    *mbuf = *mReadBuffers.begin();
1326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    mReadBuffers.erase(mReadBuffers.begin());
1336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return true;
1346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::flush() {
1376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    MediaBuffer *mbuf;
1386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (readBuffer(&mbuf)) {
1396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // there are no null buffers in the queue
1406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mbuf->release();
1416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::readBuffer(MediaBuffer **mbuf) {
1456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
1466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return queue->readBuffer(mbuf);
1476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
14972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError(
15072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
15172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
15272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
16372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
165f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuangstatus_t MediaCodecSource::Puller::setStopTimeUs(int64_t stopTimeUs) {
166f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, this);
167f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    msg->setInt64("stop-time-us", stopTimeUs);
168f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    return postSynchronouslyAndReturnError(msg);
169f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang}
170f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang
1716a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> &notify) {
17272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGV("puller (%s) start", mIsAudio ? "audio" : "video");
17372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->start(
17472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* runOnCallingThread */,
17572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* canCallJava */,
17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            PRIORITY_AUDIO);
17772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(this);
17872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mNotify = notify;
17972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
18172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", meta);
18272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
18372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
18472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
18516e79115e497386eaf010af388627f94314a55a3Chong Zhangvoid MediaCodecSource::Puller::stop() {
1866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool interrupt = false;
1876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
1886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // mark stopping before actually reaching kWhatStop on the looper, so the pulling will
1896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // stop.
1906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Queue>::Locked queue(mQueue);
1916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        queue->mPulling = false;
1926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        interrupt = queue->mReadPendingSince && (queue->mReadPendingSince < ALooper::GetNowUs() - 1000000);
1936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        queue->flush(); // flush any unprocessed pulled buffers
1946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
19516e79115e497386eaf010af388627f94314a55a3Chong Zhang
1966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (interrupt) {
19772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        interruptSource();
1986a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1996a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
20016e79115e497386eaf010af388627f94314a55a3Chong Zhang
20172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnarvoid MediaCodecSource::Puller::interruptSource() {
20272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    // call source->stop if read has been pending for over a second
20372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    // We have to call this outside the looper as looper is pending on the read.
20472e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    mSource->stop();
20572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar}
20672e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
2076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::stopSource() {
20872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
20972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    (void)postSynchronouslyAndReturnError(msg);
21072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
21172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() {
2136a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
2146a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    queue->mPaused = true;
21572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
21672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() {
2186a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
2196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    queue->mPaused = false;
22072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
22172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() {
2236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    (new AMessage(kWhatPull, this))->post();
22472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() {
2276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video");
2286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    sp<AMessage> msg = mNotify->dup();
2296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    msg->setInt32("eos", 1);
2306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    msg->post();
23172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
23272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
23372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
23472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
23572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStart:
23672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
23772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<RefBase> obj;
23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->findObject("meta", &obj));
23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            {
2416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                Mutexed<Queue>::Locked queue(mQueue);
2426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                queue->mPulling = true;
2436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
24472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
24572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->start(static_cast<MetaData *>(obj.get()));
24672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
24772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (err == OK) {
24872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                schedulePull();
24972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<AMessage> response = new AMessage;
25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->setInt32("err", err);
25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2543f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
25572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
25672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->postReply(replyID);
25772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
25872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
25972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
260f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        case kWhatSetStopTimeUs:
261f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        {
262f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            sp<AReplyToken> replyID;
263f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            CHECK(msg->senderAwaitsResponse(&replyID));
264f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            int64_t stopTimeUs;
265f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            CHECK(msg->findInt64("stop-time-us", &stopTimeUs));
266f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            status_t err = mSource->setStopTimeUs(stopTimeUs);
267f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang
268f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            sp<AMessage> response = new AMessage;
269f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            response->setInt32("err", err);
270f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            response->postReply(replyID);
271f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            break;
272f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        }
273f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang
27472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStop:
27572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
2766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mSource->stop();
27772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
27872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            sp<AMessage> response = new AMessage;
27972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            response->setInt32("err", OK);
28072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
28172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            sp<AReplyToken> replyID;
28272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
28372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            response->postReply(replyID);
28472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
28572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
28672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
28772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatPull:
28872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
2896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            Mutexed<Queue>::Locked queue(mQueue);
2906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue->mReadPendingSince = ALooper::GetNowUs();
2916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (!queue->mPulling) {
2926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                handleEOS();
29372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                break;
29472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
29572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.unlock();
2976a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            MediaBuffer *mbuf = NULL;
29872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->read(&mbuf);
2996a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.lock();
30072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3016a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue->mReadPendingSince = 0;
3026a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            // if we need to discard buffer
3036a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (!queue->mPulling || queue->mPaused || err != OK) {
3046a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                if (mbuf != NULL) {
30572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf->release();
30672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf = NULL;
30772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
3086a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                if (queue->mPulling && err == OK) {
3096a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                    msg->post(); // if simply paused, keep pulling source
3106d6c21b8d2ed66007833dae0451b0a211c97e592Wonsik Kim                    break;
3116a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                } else if (err == ERROR_END_OF_STREAM) {
31272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGV("stream ended, mbuf %p", mbuf);
3136a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                } else if (err != OK) {
31472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGE("error %d reading stream.", err);
31572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
3166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
31772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3186a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (mbuf != NULL) {
3196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                queue->pushBuffer(mbuf);
32072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
32172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.unlock();
32372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (mbuf != NULL) {
3256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                mNotify->post();
3266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                msg->post();
3276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            } else {
3286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                handleEOS();
3296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
33072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
33172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
33272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
33372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        default:
33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            TRESPASS();
33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
33672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
33772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos MolnarMediaCodecSource::Output::Output()
3396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    : mEncoderReachedEOS(false),
3406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mErrorCode(OK) {
3416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
3426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
34372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static
34472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create(
34572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
34672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &format,
34772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
348addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        const sp<PersistentSurface> &persistentSurface,
34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags) {
350addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<MediaCodecSource> mediaSource = new MediaCodecSource(
351addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            looper, format, source, persistentSurface, flags);
35272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
35372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mediaSource->init() == OK) {
35472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return mediaSource;
35572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
35672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return NULL;
35772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
35872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
35961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuangstatus_t MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
360d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector);
361d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    msg->setInt64("time-offset-us", timeOffsetUs);
36261fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang    return postSynchronouslyAndReturnError(msg);
363d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim}
364d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
365a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kimint64_t MediaCodecSource::getFirstSampleSystemTimeUs() {
366a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    sp<AMessage> msg = new AMessage(kWhatGetFirstSampleSystemTimeUs, mReflector);
367a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    sp<AMessage> response;
368a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    msg->postAndAwaitResponse(&response);
369a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    int64_t timeUs;
370a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    if (!response->findInt64("time-us", &timeUs)) {
371a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        timeUs = -1ll;
372a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    }
373a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    return timeUs;
374a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim}
375a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim
37672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) {
3771d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, mReflector);
37872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", params);
37972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
38172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
38272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() {
3831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, mReflector);
3846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return postSynchronouslyAndReturnError(msg);
38572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
38672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
387764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
388f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuangstatus_t MediaCodecSource::setStopTimeUs(int64_t stopTimeUs) {
389f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    sp<AMessage> msg = new AMessage(kWhatSetStopTimeUs, mReflector);
390764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    msg->setInt64("stop-time-us", stopTimeUs);
391764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    return postSynchronouslyAndReturnError(msg);
392764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang}
393764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
394764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangstatus_t MediaCodecSource::pause(MetaData* params) {
395764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    sp<AMessage> msg = new AMessage(kWhatPause, mReflector);
396764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    msg->setObject("meta", params);
397764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    msg->post();
39872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
39972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
40072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
401ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnarsp<MetaData> MediaCodecSource::getFormat() {
402ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    Mutexed<sp<MetaData>>::Locked meta(mMeta);
403ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    return *meta;
404ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar}
405ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar
40672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() {
40772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
40872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return mGraphicBufferProducer;
40972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
41072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaCodecSource::read(
41284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        MediaBuffer** buffer, const ReadOptions* /* options */) {
4136a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Output>::Locked output(mOutput);
41472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    *buffer = NULL;
4166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (output->mBufferQueue.size() == 0 && !output->mEncoderReachedEOS) {
4176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output.waitForCondition(output->mCond);
41872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
4196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (!output->mEncoderReachedEOS) {
4206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        *buffer = *output->mBufferQueue.begin();
4216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mBufferQueue.erase(output->mBufferQueue.begin());
42272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
42372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
4246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return output->mErrorCode;
42572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
42672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) {
42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->setObserver(0);
42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->release();
43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43272cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource(
43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &outputFormat,
43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
436addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        const sp<PersistentSurface> &persistentSurface,
43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags)
43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mLooper(looper),
43972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mOutputFormat(outputFormat),
44072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mMeta(new MetaData),
44172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFlags(flags),
44272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mIsVideo(false),
44372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStarted(false),
44472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStopping(false),
44572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mDoMoreWorkPending(false),
446c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mSetEncoderFormat(false),
447c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderFormat(0),
448c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderDataSpace(0),
449addf2cbb120346ae42e78fa739245a353db5edadChong Zhang      mPersistentSurface(persistentSurface),
450d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim      mInputBufferTimeOffsetUs(0),
451a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim      mFirstSampleSystemTimeUs(-1ll),
452a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim      mPausePending(false),
45372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFirstSampleTimeUs(-1ll),
4546a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mGeneration(0) {
45572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mLooper != NULL);
45672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
45772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString mime;
45872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &mime));
45972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!strncasecmp("video/", mime.c_str(), 6)) {
46172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mIsVideo = true;
46272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
46372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
46572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mPuller = new Puller(source);
46672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
46772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
46872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46972cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() {
47072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    releaseEncoder();
47172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->stop();
47372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(mReflector->id());
47472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
47572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() {
47772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = initEncoder();
47872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
48072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        releaseEncoder();
48172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
48272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
48472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
48572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() {
48772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mReflector = new AHandlerReflector<MediaCodecSource>(this);
48872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(mReflector);
48972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper = new ALooper;
49172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->setName("codec_looper");
49272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->start();
49372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
49572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputFormat->setInt32("create-input-buffers-suspended", 1);
49672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
49772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString outputMIME;
49972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &outputMIME));
50072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
50116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    Vector<AString> matchingCodecs;
50216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    MediaCodecList::findMatchingCodecs(
50316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            outputMIME.c_str(), true /* encoder */,
50416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            ((mFlags & FLAG_PREFER_SOFTWARE_CODEC) ? MediaCodecList::kPreferSoftwareCodecs : 0),
50516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            &matchingCodecs);
50672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
50716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    status_t err = NO_INIT;
50816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    for (size_t ix = 0; ix < matchingCodecs.size(); ++ix) {
50916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = MediaCodec::CreateByComponentName(
51016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                mCodecLooper, matchingCodecs[ix]);
51116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
51216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (mEncoder == NULL) {
51316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            continue;
51416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
51516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
51616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
51772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
51816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector);
51916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->setCallback(mEncoderActivityNotify);
52072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        err = mEncoder->configure(
52216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    mOutputFormat,
52316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* nativeWindow */,
52416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* crypto */,
52516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    MediaCodec::CONFIGURE_FLAG_ENCODE);
526421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
52716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (err == OK) {
52816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            break;
52916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
53016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->release();
53116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = NULL;
53216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    }
53372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
53472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
53572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
53672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
53772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
53872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->getOutputFormat(&mOutputFormat);
539ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    sp<MetaData> meta = new MetaData;
540ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    convertMessageToMetaData(mOutputFormat, meta);
541ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar    mMeta.lock().set(meta);
54272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
54372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
54472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mIsVideo);
54572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
546addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        if (mPersistentSurface != NULL) {
547e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // When using persistent surface, we are only interested in the
548e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // consumer, but have to use PersistentSurface as a wrapper to
549e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // pass consumer over messages (similar to BufferProducerWrapper)
550addf2cbb120346ae42e78fa739245a353db5edadChong Zhang            err = mEncoder->setInputSurface(mPersistentSurface);
551e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        } else {
552e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            err = mEncoder->createInputSurface(&mGraphicBufferProducer);
553e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        }
55472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
55572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
55672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
55772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
55872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
55972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
560c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    sp<AMessage> inputFormat;
561c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    int32_t usingSwReadOften;
562c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    mSetEncoderFormat = false;
563b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (mEncoder->getInputFormat(&inputFormat) == OK) {
564c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mSetEncoderFormat = true;
565b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (inputFormat->findInt32("using-sw-read-often", &usingSwReadOften)
566b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                && usingSwReadOften) {
567b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            // this is a SW encoder; signal source to allocate SW readable buffers
568b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mEncoderFormat = kDefaultSwVideoEncoderFormat;
569b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        } else {
570b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mEncoderFormat = kDefaultHwVideoEncoderFormat;
571b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
572b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if (!inputFormat->findInt32("android._dataspace", &mEncoderDataSpace)) {
573b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            mEncoderDataSpace = kDefaultVideoEncoderDataSpace;
574b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
575b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGV("setting dataspace %#x, format %#x", mEncoderDataSpace, mEncoderFormat);
576c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
577c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
5781099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan    err = mEncoder->start();
57972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
58072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
58172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
58272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
58372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
5856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Output>::Locked output(mOutput);
5866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mEncoderReachedEOS = false;
5876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mErrorCode = OK;
5886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
58972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
59072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
59172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
59272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
59372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() {
59472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder == NULL) {
59572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return;
59672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
59772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
59872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->release();
59972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder.clear();
60072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
60172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError(
60372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
60472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
60572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
60672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
60772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
60872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
60972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
61472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
61672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
61772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) {
6196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool reachedEOS = false;
6206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
6216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Output>::Locked output(mOutput);
6226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        reachedEOS = output->mEncoderReachedEOS;
6236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (!reachedEOS) {
6246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("encoder (%s) reached EOS", mIsVideo ? "video" : "audio");
62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // release all unread media buffers
6266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            for (List<MediaBuffer*>::iterator it = output->mBufferQueue.begin();
6276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                    it != output->mBufferQueue.end(); it++) {
62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                (*it)->release();
62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
6306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mBufferQueue.clear();
6316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mEncoderReachedEOS = true;
6326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mErrorCode = err;
6336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mCond.signal();
6346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
6356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            reachedEOS = true;
6366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output.unlock();
6376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            releaseEncoder();
63872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
63972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
6406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
6416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (mStopping && reachedEOS) {
64216e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio");
6436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mPuller->stopSource();
6446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
64572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // posting reply to everyone that's waiting
6463f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        List<sp<AReplyToken>>::iterator it;
64772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        for (it = mStopReplyIDQueue.begin();
64872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                it != mStopReplyIDQueue.end(); it++) {
64972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(*it);
65072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
65172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.clear();
65272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = false;
6536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        ++mGeneration;
65472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
65572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
65672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
657764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangvoid MediaCodecSource::resume(int64_t resumeStartTimeUs) {
65872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
65972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder != NULL) {
66072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> params = new AMessage;
66172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        params->setInt32("drop-input-frames", false);
662764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (resumeStartTimeUs > 0) {
663764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            params->setInt64("drop-start-time-us", resumeStartTimeUs);
66472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
66572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mEncoder->setParameters(params);
66672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
66872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() {
6706a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    MediaBuffer* mbuf = NULL;
6716a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (!mAvailEncoderInputIndices.empty() && mPuller->readBuffer(&mbuf)) {
67272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
67372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
67472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
67572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        int64_t timeUs = 0ll;
67672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags = 0;
67772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t size = 0;
67872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
67972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mbuf != NULL) {
68072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
681a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            if (mFirstSampleSystemTimeUs < 0ll) {
682a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                mFirstSampleSystemTimeUs = systemTime() / 1000;
683a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                if (mPausePending) {
684a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                    mPausePending = false;
685764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                    onPause(mFirstSampleSystemTimeUs);
686a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                    mbuf->release();
687a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                    mAvailEncoderInputIndices.push_back(bufferIndex);
688a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                    return OK;
689a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                }
690a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            }
691a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim
692d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim            timeUs += mInputBufferTimeOffsetUs;
69372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // push decoding time for video, or drift time for audio
69572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
69672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDecodingTimeQueue.push_back(timeUs);
69772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
69872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME
69972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mFirstSampleTimeUs < 0ll) {
70072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mFirstSampleTimeUs = timeUs;
70172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
70272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                int64_t driftTimeUs = 0;
70372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs)
70472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                        && driftTimeUs) {
70572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs;
70672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
70772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDriftTimeQueue.push_back(driftTimeUs);
70872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME
70972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
71072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7117e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            sp<MediaCodecBuffer> inbuf;
7121099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf);
713e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George
714e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George            if (err != OK || inbuf == NULL || inbuf->data() == NULL
715e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George                    || mbuf->data() == NULL || mbuf->size() == 0) {
7161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->release();
7171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
7181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
7191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
7201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
72172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            size = mbuf->size();
72272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            memcpy(inbuf->data(), mbuf->data(), size);
72472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
72572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
72672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // video encoder will release MediaBuffer when done
72772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // with underlying data.
7281099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                inbuf->setMediaBufferBase(mbuf);
72972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
73072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mbuf->release();
73172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
73272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
73372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            flags = MediaCodec::BUFFER_FLAG_EOS;
73472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
73572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
73672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err = mEncoder->queueInputBuffer(
73772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                bufferIndex, 0, size, timeUs, flags);
73872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
73972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
74072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
74172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
74272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
74372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
74472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
74572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
74672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
74772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) {
74872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStopping) {
74972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGE("Failed to start while we're stopping");
75072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return INVALID_OPERATION;
75172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
752764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    int64_t startTimeUs;
753764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
754764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        startTimeUs = -1ll;
755764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
75672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
75772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStarted) {
75872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio");
759a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        if (mPausePending) {
760a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            mPausePending = false;
761a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            return OK;
762a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        }
7634cca134f0a775808458622490886d775c59bcc54Wonsik Kim        if (mIsVideo) {
7644cca134f0a775808458622490886d775c59bcc54Wonsik Kim            mEncoder->requestIDRFrame();
7654cca134f0a775808458622490886d775c59bcc54Wonsik Kim        }
76672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
767764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            resume(startTimeUs);
76872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
76972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mPuller != NULL);
77072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPuller->resume();
77172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
77272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
77372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
77472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
77572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio");
77672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
77772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = OK;
77872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
77972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
780764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (mEncoder != NULL) {
781764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            sp<AMessage> params = new AMessage;
782764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            params->setInt32("drop-input-frames", false);
783764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            if (startTimeUs >= 0) {
784764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                params->setInt64("skip-frames-before", startTimeUs);
785764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
786764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            mEncoder->setParameters(params);
78772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
78872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    } else {
78972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mPuller != NULL);
790c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        sp<MetaData> meta = params;
791c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mSetEncoderFormat) {
792c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            if (meta == NULL) {
793c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                meta = new MetaData;
794c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            }
795c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyPixelFormat, mEncoderFormat);
796c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyColorSpace, mEncoderDataSpace);
797c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
798c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
7991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector);
800c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        err = mPuller->start(meta.get(), notify);
80172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
80272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
80372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
80472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
80572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
80672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio");
80772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
80872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mStarted = true;
80972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
81072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
81172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
812764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuangvoid MediaCodecSource::onPause(int64_t pauseStartTimeUs) {
813764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    if ((mFlags & FLAG_USE_SURFACE_INPUT) && (mEncoder != NULL)) {
814764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        sp<AMessage> params = new AMessage;
815764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        params->setInt32("drop-input-frames", true);
816764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        params->setInt64("drop-start-time-us", pauseStartTimeUs);
817764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        mEncoder->setParameters(params);
818a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    } else {
819a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        CHECK(mPuller != NULL);
820a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        mPuller->pause();
821a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    }
822a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim}
823a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim
82472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
82572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
82672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPullerNotify:
82772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
8286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int32_t eos = 0;
8296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (msg->findInt32("eos", &eos) && eos) {
8306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("puller (%s) reached EOS", mIsVideo ? "video" : "audio");
83116e79115e497386eaf010af388627f94314a55a3Chong Zhang            signalEOS();
8326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            break;
83372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
83472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
83572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
8366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str());
83772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
83872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
83972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
84072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        feedEncoderInputBuffers();
84172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
84272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
84372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatEncoderActivity:
84472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
84572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
84672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
84772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
84872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        int32_t cbID;
8501099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        CHECK(msg->findInt32("callbackID", &cbID));
8511099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        if (cbID == MediaCodec::CB_INPUT_AVAILABLE) {
8521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
8531099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
8541099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mAvailEncoderInputIndices.push_back(index);
8561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            feedEncoderInputBuffers();
85758fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar        } else if (cbID == MediaCodec::CB_OUTPUT_FORMAT_CHANGED) {
85858fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            status_t err = mEncoder->getOutputFormat(&mOutputFormat);
85958fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            if (err != OK) {
86058fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                signalEOS(err);
86158fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar                break;
86258fb7c6e1a9244dd7215a647388c440d8d75851bLajos Molnar            }
863ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar            sp<MetaData> meta = new MetaData;
864ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar            convertMessageToMetaData(mOutputFormat, meta);
865ee0eba046f666303741a5a5f70afad17030cc8b1Lajos Molnar            mMeta.lock().set(meta);
8661099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) {
8671099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
8681099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t offset;
8691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t size;
8701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int64_t timeUs;
8711099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t flags;
8721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
8741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("offset", &offset));
8751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("size", &size));
8761099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt64("timeUs", &timeUs));
8771099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("flags", &flags));
8781099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8791099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_EOS) {
8801099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mEncoder->releaseOutputBuffer(index);
8811099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
8821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
8831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
884f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
8857e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            sp<MediaCodecBuffer> outbuf;
8861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getOutputBuffer(index, &outbuf);
887e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George            if (err != OK || outbuf == NULL || outbuf->data() == NULL
888e36e1034c2938559c96d1e765b3c75380c83ff6bHaynes Mathew George                || outbuf->size() == 0) {
8891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
8901099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
8911099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
892f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
8931099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            MediaBuffer *mbuf = new MediaBuffer(outbuf->size());
89401d1e525584d037b80d7c9ab79010fd2a5b9a870Andy Hung            mbuf->setObserver(this);
895a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            mbuf->add_ref();
89672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8971099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) {
8981099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                if (mIsVideo) {
8991099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t decodingTimeUs;
9001099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    if (mFlags & FLAG_USE_SURFACE_INPUT) {
901a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                        if (mFirstSampleSystemTimeUs < 0ll) {
902a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                            mFirstSampleSystemTimeUs = systemTime() / 1000;
903a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                            if (mPausePending) {
904a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                                mPausePending = false;
905764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                                onPause(mFirstSampleSystemTimeUs);
906a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                                mbuf->release();
907a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                                break;
908a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                            }
909a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim                        }
91061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang                        // Timestamp offset is already adjusted in GraphicBufferSource.
911e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim                        // GraphicBufferSource is supposed to discard samples
912e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim                        // queued before start, and offset timeUs by start time
913e35600eb62d4a2dc2dd0cc8c0d0d177cec7ed1ccWonsik Kim                        CHECK_GE(timeUs, 0ll);
9141099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // TODO:
9151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // Decoding time for surface source is unavailable,
9161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // use presentation time for now. May need to move
9171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // this logic into MediaCodec.
9181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = timeUs;
9191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    } else {
9201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        CHECK(!mDecodingTimeQueue.empty());
9211099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = *(mDecodingTimeQueue.begin());
9221099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        mDecodingTimeQueue.erase(mDecodingTimeQueue.begin());
9231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    }
9241099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
92572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9261099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64,
9271099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, decodingTimeUs - timeUs);
9281099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                } else {
9291099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t driftTimeUs = 0;
9301099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#if DEBUG_DRIFT_TIME
9311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    CHECK(!mDriftTimeQueue.empty());
9321099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    driftTimeUs = *(mDriftTimeQueue.begin());
9331099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mDriftTimeQueue.erase(mDriftTimeQueue.begin());
9341099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs);
9351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#endif // DEBUG_DRIFT_TIME
9361099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64,
9371099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, driftTimeUs);
9381099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                }
9391099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt64(kKeyTime, timeUs);
9401099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            } else {
9418f889be4754d40f39c9377b055988f58f3ed64a8Hangyu Kuang                mbuf->meta_data()->setInt64(kKeyTime, 0ll);
9421099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true);
9431099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
9441099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
9451099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true);
9461099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
947a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            memcpy(mbuf->data(), outbuf->data(), outbuf->size());
9481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
9491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            {
9506a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                Mutexed<Output>::Locked output(mOutput);
9516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                output->mBufferQueue.push_back(mbuf);
9526a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                output->mCond.signal();
9531099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
9541099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
9551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mEncoder->releaseOutputBuffer(index);
9561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       } else if (cbID == MediaCodec::CB_ERROR) {
9571099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err;
9581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("err", &err));
9591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            ALOGE("Encoder (%s) reported error : 0x%x",
9601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mIsVideo ? "video" : "audio", err);
961c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan            if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
962c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan                mStopping = true;
963c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan                mPuller->stop();
964c68689dfd6fa3b880a0d8e75408b582b389630f8Praveen Chavan            }
9651099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            signalEOS();
9661099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       }
9671099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       break;
96872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
96972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStart:
97072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
9713f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
97272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
97372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
97472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<RefBase> obj;
97572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->findObject("meta", &obj));
97672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        MetaData *params = static_cast<MetaData *>(obj.get());
97772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
97872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> response = new AMessage;
97972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->setInt32("err", onStart(params));
98072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->postReply(replyID);
98172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
98272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
98372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStop:
98472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
98516e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio");
98672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9873f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
98872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
98972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (mOutput.lock()->mEncoderReachedEOS) {
99172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // if we already reached EOS, reply and return now
99216e79115e497386eaf010af388627f94314a55a3Chong Zhang            ALOGI("encoder (%s) already stopped",
99372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mIsVideo ? "video" : "audio");
99472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(replyID);
99572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
99672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
99772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
99872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.push_back(replyID);
99972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mStopping) {
100072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // nothing to do if we're already stopping, reply will be posted
100172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // to all when we're stopped.
100272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
100372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
100472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
100572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = true;
100672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1007f72cefddf378909f360998852e41f49042711299Hangyu Kuang        int64_t timeoutUs = kStopTimeoutUs;
100872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // if using surface, signal source EOS and wait for EOS to come back.
10096a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // otherwise, stop puller (which also clears the input buffer queue)
10106a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // and wait for the EOS message. We cannot call source->stop() because
10116a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // the encoder may still be processing input buffers.
101272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
101372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mEncoder->signalEndOfInputStream();
1014f72cefddf378909f360998852e41f49042711299Hangyu Kuang            // Increase the timeout if there is delay in the GraphicBufferSource
1015f72cefddf378909f360998852e41f49042711299Hangyu Kuang            sp<AMessage> inputFormat;
1016f72cefddf378909f360998852e41f49042711299Hangyu Kuang            int64_t stopTimeOffsetUs;
1017f72cefddf378909f360998852e41f49042711299Hangyu Kuang            if (mEncoder->getInputFormat(&inputFormat) == OK &&
1018f72cefddf378909f360998852e41f49042711299Hangyu Kuang                    inputFormat->findInt64("android._stop-time-offset-us", &stopTimeOffsetUs) &&
1019f72cefddf378909f360998852e41f49042711299Hangyu Kuang                    stopTimeOffsetUs > 0) {
1020f72cefddf378909f360998852e41f49042711299Hangyu Kuang                timeoutUs += stopTimeOffsetUs;
1021f72cefddf378909f360998852e41f49042711299Hangyu Kuang            }
102272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
10236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mPuller->stop();
102472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
10256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
10266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // complete stop even if encoder/puller stalled
10276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        sp<AMessage> timeoutMsg = new AMessage(kWhatStopStalled, mReflector);
10286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        timeoutMsg->setInt32("generation", mGeneration);
1029f72cefddf378909f360998852e41f49042711299Hangyu Kuang        timeoutMsg->post(timeoutUs);
103072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
103172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
10326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
10336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    case kWhatStopStalled:
10346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
10356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int32_t generation;
10366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        CHECK(msg->findInt32("generation", &generation));
10376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (generation != mGeneration) {
10386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar             break;
10396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        }
10406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
10416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
10426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("source (%s) stopping", mIsVideo ? "video" : "audio");
104372e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            mPuller->interruptSource();
10446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
10456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        }
10466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        signalEOS();
1047764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        break;
10486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
10496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
105072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPause:
105172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
1052a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        if (mFirstSampleSystemTimeUs < 0) {
1053a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim            mPausePending = true;
105472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
1055764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            sp<RefBase> obj;
1056764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            CHECK(msg->findObject("meta", &obj));
1057764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            MetaData *params = static_cast<MetaData *>(obj.get());
1058764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            int64_t pauseStartTimeUs = -1;
1059764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            if (params == NULL || !params->findInt64(kKeyTime, &pauseStartTimeUs)) {
1060764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang                pauseStartTimeUs = -1ll;
1061764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            }
1062764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            onPause(pauseStartTimeUs);
106372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
106472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
106572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
1066d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    case kWhatSetInputBufferTimeOffset:
1067d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    {
1068d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AReplyToken> replyID;
1069d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->senderAwaitsResponse(&replyID));
107061fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        status_t err = OK;
1071d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs));
1072d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
107361fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        // Propagate the timestamp offset to GraphicBufferSource.
10746d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
107561fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            sp<AMessage> params = new AMessage;
107661fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            params->setInt64("time-offset-us", mInputBufferTimeOffsetUs);
107761fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang            err = mEncoder->setParameters(params);
107861fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        }
107961fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang
1080d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AMessage> response = new AMessage;
108161fcfd1b0b58dff9284ede8dc49749ca7395856dHangyu Kuang        response->setInt32("err", err);
1082d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        response->postReply(replyID);
1083d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        break;
1084d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    }
1085f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang    case kWhatSetStopTimeUs:
1086764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    {
1087764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        sp<AReplyToken> replyID;
1088764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        CHECK(msg->senderAwaitsResponse(&replyID));
1089764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        status_t err = OK;
1090764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        int64_t stopTimeUs;
1091764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        CHECK(msg->findInt64("stop-time-us", &stopTimeUs));
1092764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1093f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        // Propagate the stop time to GraphicBufferSource.
1094764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
1095764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            sp<AMessage> params = new AMessage;
1096764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            params->setInt64("stop-time-us", stopTimeUs);
1097764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang            err = mEncoder->setParameters(params);
1098f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang        } else {
1099f8754cc59cdea9026ee4e1c821a6c362c55da7f8Hangyu Kuang            err = mPuller->setStopTimeUs(stopTimeUs);
1100764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        }
1101764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang
1102764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        sp<AMessage> response = new AMessage;
1103764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        response->setInt32("err", err);
1104764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        response->postReply(replyID);
1105764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang        break;
1106764d945bfdb9dec60f2b482fbf6c5e83824ed950Hangyu Kuang    }
1107a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    case kWhatGetFirstSampleSystemTimeUs:
1108a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    {
1109a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        sp<AReplyToken> replyID;
1110a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        CHECK(msg->senderAwaitsResponse(&replyID));
1111a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim
1112a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        sp<AMessage> response = new AMessage;
1113a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        response->setInt64("time-us", mFirstSampleSystemTimeUs);
1114a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        response->postReply(replyID);
1115a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim        break;
1116a5aeb87eabfda3cb385eed405b843bdcb64252beWonsik Kim    }
111772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    default:
111872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        TRESPASS();
111972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
112072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
112172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
112272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android
1123