MediaCodecSource.cpp revision 6a3a56fbcd6c01c3895f14e43858971b0edca9b2
172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang/*
272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Copyright 2014, The Android Open Source Project
372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *
472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Licensed under the Apache License, Version 2.0 (the "License");
572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * you may not use this file except in compliance with the License.
672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * You may obtain a copy of the License at
772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *
872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *     http://www.apache.org/licenses/LICENSE-2.0
972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang *
1072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * Unless required by applicable law or agreed to in writing, software
1172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * distributed under the License is distributed on an "AS IS" BASIS,
1272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * See the License for the specific language governing permissions and
1472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang * limitations under the License.
1572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang */
1672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang//#define LOG_NDEBUG 0
1872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#define LOG_TAG "MediaCodecSource"
1972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#define DEBUG_DRIFT_TIME 0
20a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn
21a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h>
22a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn
23e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <gui/IGraphicBufferConsumer.h>
2472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <gui/IGraphicBufferProducer.h>
2572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <gui/Surface.h>
2672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/ICrypto.h>
2772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ABuffer.h>
2872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ADebug.h>
2972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/ALooper.h>
3072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/foundation/AMessage.h>
3172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaBuffer.h>
3272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaCodec.h>
3316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar#include <media/stagefright/MediaCodecList.h>
34e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <media/stagefright/MediaCodecSource.h>
3572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaErrors.h>
3672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/MediaSource.h>
37e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <media/stagefright/MetaData.h>
38e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang#include <media/stagefright/PersistentSurface.h>
3972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#include <media/stagefright/Utils.h>
4072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangnamespace android {
4272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnarconst int kDefaultSwVideoEncoderFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
44c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnarconst int kDefaultSwVideoEncoderDataSpace = HAL_DATASPACE_BT709;
45c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarconst int kStopTimeoutUs = 300000; // allow 1 sec for shutting down encoder
476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
4872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource::Puller : public AHandler {
4972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    Puller(const sp<MediaSource> &source);
5072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t start(const sp<MetaData> &meta, const sp<AMessage> &notify);
5216e79115e497386eaf010af388627f94314a55a3Chong Zhang    void stop();
536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    void stopSource();
5472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void pause();
5572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void resume();
5672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool readBuffer(MediaBuffer **buffer);
586a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
5972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected:
6072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual void onMessageReceived(const sp<AMessage> &msg);
6172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual ~Puller();
6272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate:
6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    enum {
6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStart = 'msta',
6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStop,
6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatPull,
6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    };
6972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaSource> mSource;
7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> mNotify;
7272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<ALooper> mLooper;
7372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mIsAudio;
746a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
756a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    struct Queue {
766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Queue()
776a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            : mReadPendingSince(0),
786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar              mPaused(false),
796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar              mPulling(false) { }
806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int64_t mReadPendingSince;
816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mPaused;
826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mPulling;
836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Vector<MediaBuffer *> mReadBuffers;
846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        void flush();
866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // if queue is empty, return false and set *|buffer| to NULL . Otherwise, pop
876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // buffer from front of the queue, place it into *|buffer| and return true.
886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool readBuffer(MediaBuffer **buffer);
896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // add a buffer to the back of the queue
906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        void pushBuffer(MediaBuffer *mbuf);
916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    };
926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue> mQueue;
9372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
9572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void schedulePull();
9672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void handleEOS();
9772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(Puller);
9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang};
10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10172cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source)
10272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mSource(source),
10372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mLooper(new ALooper()),
1046a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mIsAudio(false)
1056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar{
10672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MetaData> meta = source->getFormat();
10772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    const char *mime;
10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(meta->findCString(kKeyMIMEType, &mime));
10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mIsAudio = !strncasecmp(mime, "audio/", 6);
11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->setName("pull_looper");
11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11572cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() {
11672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(id());
11772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->stop();
11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::pushBuffer(MediaBuffer *mbuf) {
1216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    mReadBuffers.push_back(mbuf);
1226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::Queue::readBuffer(MediaBuffer **mbuf) {
1256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (mReadBuffers.empty()) {
1266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        *mbuf = NULL;
1276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        return false;
1286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    *mbuf = *mReadBuffers.begin();
1306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    mReadBuffers.erase(mReadBuffers.begin());
1316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return true;
1326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::flush() {
1356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    MediaBuffer *mbuf;
1366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (readBuffer(&mbuf)) {
1376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // there are no null buffers in the queue
1386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mbuf->release();
1396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::readBuffer(MediaBuffer **mbuf) {
1436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
1446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return queue->readBuffer(mbuf);
1456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
14772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError(
14872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
14972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
15072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
15172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
15472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
15872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1636a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> &notify) {
16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGV("puller (%s) start", mIsAudio ? "audio" : "video");
16572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->start(
16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* runOnCallingThread */,
16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* canCallJava */,
16872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            PRIORITY_AUDIO);
16972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(this);
17072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mNotify = notify;
17172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
17372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", meta);
17472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
17572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
17716e79115e497386eaf010af388627f94314a55a3Chong Zhangvoid MediaCodecSource::Puller::stop() {
1786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool interrupt = false;
1796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
1806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // mark stopping before actually reaching kWhatStop on the looper, so the pulling will
1816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // stop.
1826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Queue>::Locked queue(mQueue);
1836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        queue->mPulling = false;
1846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        interrupt = queue->mReadPendingSince && (queue->mReadPendingSince < ALooper::GetNowUs() - 1000000);
1856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        queue->flush(); // flush any unprocessed pulled buffers
1866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
18716e79115e497386eaf010af388627f94314a55a3Chong Zhang
1886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (interrupt) {
1896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // call source->stop if read has been pending for over a second
1906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // TODO: we should really call this if kWhatStop has not returned for more than a second.
1916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mSource->stop();
1926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
19416e79115e497386eaf010af388627f94314a55a3Chong Zhang
1956a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::stopSource() {
1961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStop, this))->post();
19772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
19872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
19972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() {
2006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
2016a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    queue->mPaused = true;
20272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
20372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
20472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() {
2056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
2066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    queue->mPaused = false;
20772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
20872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
20972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() {
2106a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    (new AMessage(kWhatPull, this))->post();
21172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
21272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() {
2146a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video");
2156a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    sp<AMessage> msg = mNotify->dup();
2166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    msg->setInt32("eos", 1);
2176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    msg->post();
21872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
21972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
22172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
22272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStart:
22372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
22472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<RefBase> obj;
22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->findObject("meta", &obj));
22672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            {
2286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                Mutexed<Queue>::Locked queue(mQueue);
2296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                queue->mPulling = true;
2306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
23172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
23272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->start(static_cast<MetaData *>(obj.get()));
23372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
23472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (err == OK) {
23572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                schedulePull();
23672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
23772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<AMessage> response = new AMessage;
23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->setInt32("err", err);
24072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2413f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
24272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
24372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->postReply(replyID);
24472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
24572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
24672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
24772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStop:
24872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
2496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mSource->stop();
25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatPull:
25472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
2556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            Mutexed<Queue>::Locked queue(mQueue);
2566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue->mReadPendingSince = ALooper::GetNowUs();
2576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (!queue->mPulling) {
2586a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                handleEOS();
25972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                break;
26072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
26172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2626a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.unlock();
2636a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            MediaBuffer *mbuf = NULL;
26472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->read(&mbuf);
2656a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.lock();
26672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2676a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue->mReadPendingSince = 0;
2686a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            // if we need to discard buffer
2696a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (!queue->mPulling || queue->mPaused || err != OK) {
2706a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                if (mbuf != NULL) {
27172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf->release();
27272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf = NULL;
27372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
2746a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                if (queue->mPulling && err == OK) {
2756a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                    msg->post(); // if simply paused, keep pulling source
2766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                } else if (err == ERROR_END_OF_STREAM) {
27772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGV("stream ended, mbuf %p", mbuf);
2786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                } else if (err != OK) {
27972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGE("error %d reading stream.", err);
28072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
2816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
28272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (mbuf != NULL) {
2846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                queue->pushBuffer(mbuf);
28572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
28672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.unlock();
28872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (mbuf != NULL) {
2906a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                mNotify->post();
2916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                msg->post();
2926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            } else {
2936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                handleEOS();
2946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
29572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
29672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
29772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
29872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        default:
29972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            TRESPASS();
30072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
30172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
30272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3036a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos MolnarMediaCodecSource::Output::Output()
3046a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    : mEncoderReachedEOS(false),
3056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mErrorCode(OK) {
3066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
3076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
30872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static
30972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create(
31072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
31172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &format,
31272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
313e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        const sp<IGraphicBufferConsumer> &consumer,
31472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags) {
31572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaCodecSource> mediaSource =
316e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            new MediaCodecSource(looper, format, source, consumer, flags);
31772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
31872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mediaSource->init() == OK) {
31972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return mediaSource;
32072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
32172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return NULL;
32272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
32372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
324d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kimvoid MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
325d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector);
326d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    msg->setInt64("time-offset-us", timeOffsetUs);
327d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    postSynchronouslyAndReturnError(msg);
328d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim}
329d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
33072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) {
3311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, mReflector);
33272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", params);
33372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
33672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() {
3371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, mReflector);
3386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return postSynchronouslyAndReturnError(msg);
33972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
34072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
34172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::pause() {
3421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatPause, mReflector))->post();
34372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
34472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
34572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
34672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() {
34772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
34872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return mGraphicBufferProducer;
34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
35072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
35184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaCodecSource::read(
35284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        MediaBuffer** buffer, const ReadOptions* /* options */) {
3536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Output>::Locked output(mOutput);
35472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
35572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    *buffer = NULL;
3566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (output->mBufferQueue.size() == 0 && !output->mEncoderReachedEOS) {
3576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output.waitForCondition(output->mCond);
35872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
3596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (!output->mEncoderReachedEOS) {
3606a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        *buffer = *output->mBufferQueue.begin();
3616a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mBufferQueue.erase(output->mBufferQueue.begin());
36272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
36372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
3646a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return output->mErrorCode;
36572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
36672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
36772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) {
36872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->setObserver(0);
36972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->release();
37072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
37172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
37272cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource(
37372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
37472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &outputFormat,
37572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
376e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        const sp<IGraphicBufferConsumer> &consumer,
37772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags)
37872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mLooper(looper),
37972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mOutputFormat(outputFormat),
38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mMeta(new MetaData),
38172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFlags(flags),
38272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mIsVideo(false),
38372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStarted(false),
38472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStopping(false),
38572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mDoMoreWorkPending(false),
386c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mSetEncoderFormat(false),
387c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderFormat(0),
388c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderDataSpace(0),
389e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang      mGraphicBufferConsumer(consumer),
390d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim      mInputBufferTimeOffsetUs(0),
39172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFirstSampleTimeUs(-1ll),
3926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mGeneration(0) {
39372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mLooper != NULL);
39472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
39572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString mime;
39672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &mime));
39772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
39872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!strncasecmp("video/", mime.c_str(), 6)) {
39972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mIsVideo = true;
40072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
40172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
40272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
40372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mPuller = new Puller(source);
40472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
40572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
40672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
40772cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() {
40872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    releaseEncoder();
40972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->stop();
41172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(mReflector->id());
41272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
41372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() {
41572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = initEncoder();
41672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
41872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        releaseEncoder();
41972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
42072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
42272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
42372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() {
42572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mReflector = new AHandlerReflector<MediaCodecSource>(this);
42672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(mReflector);
42772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper = new ALooper;
42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->setName("codec_looper");
43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->start();
43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_METADATA_INPUT) {
43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputFormat->setInt32("store-metadata-in-buffers", 1);
43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputFormat->setInt32("create-input-buffers-suspended", 1);
43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
43972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
44072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString outputMIME;
44172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &outputMIME));
44272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
44316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    Vector<AString> matchingCodecs;
44416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    MediaCodecList::findMatchingCodecs(
44516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            outputMIME.c_str(), true /* encoder */,
44616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            ((mFlags & FLAG_PREFER_SOFTWARE_CODEC) ? MediaCodecList::kPreferSoftwareCodecs : 0),
44716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            &matchingCodecs);
44872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
44916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    status_t err = NO_INIT;
45016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    for (size_t ix = 0; ix < matchingCodecs.size(); ++ix) {
45116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = MediaCodec::CreateByComponentName(
45216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                mCodecLooper, matchingCodecs[ix]);
45316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
45416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (mEncoder == NULL) {
45516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            continue;
45616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
45716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
45816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
45972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector);
46116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->setCallback(mEncoderActivityNotify);
46272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        err = mEncoder->configure(
46416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    mOutputFormat,
46516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* nativeWindow */,
46616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* crypto */,
46716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    MediaCodec::CONFIGURE_FLAG_ENCODE);
468421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
46916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (err == OK) {
47016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            break;
47116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
47216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->release();
47316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = NULL;
47416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    }
47572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
47772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
47872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
47972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->getOutputFormat(&mOutputFormat);
48172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    convertMessageToMetaData(mOutputFormat, mMeta);
48272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
48472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mIsVideo);
48572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
486e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        if (mGraphicBufferConsumer != NULL) {
487e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // When using persistent surface, we are only interested in the
488e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // consumer, but have to use PersistentSurface as a wrapper to
489e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // pass consumer over messages (similar to BufferProducerWrapper)
4908f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            err = mEncoder->setInputSurface(
491e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang                    new PersistentSurface(NULL, mGraphicBufferConsumer));
492e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        } else {
493e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            err = mEncoder->createInputSurface(&mGraphicBufferProducer);
494e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        }
49572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
49772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
49872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
49972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
50072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
501c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    sp<AMessage> inputFormat;
502c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    int32_t usingSwReadOften;
503c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    mSetEncoderFormat = false;
504c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    if (mEncoder->getInputFormat(&inputFormat) == OK
505c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            && inputFormat->findInt32("using-sw-read-often", &usingSwReadOften)
506c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            && usingSwReadOften) {
507c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        // this is a SW encoder; signal source to allocate SW readable buffers
508c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mSetEncoderFormat = true;
509c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mEncoderFormat = kDefaultSwVideoEncoderFormat;
510c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mEncoderDataSpace = kDefaultSwVideoEncoderDataSpace;
511c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
512c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
5131099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan    err = mEncoder->start();
51472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
51572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
51672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
51772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
51872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
5206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Output>::Locked output(mOutput);
5216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mEncoderReachedEOS = false;
5226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mErrorCode = OK;
5236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
52472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
52672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
52772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() {
52972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder == NULL) {
53072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return;
53172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
53272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
53372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->release();
53472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder.clear();
53572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
53672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
53772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError(
53872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
53972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
54072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
54172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
54272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
54372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
54472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
54572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
54672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
54772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
54872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
54972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
55072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
55172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
55272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
55372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) {
5546a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool reachedEOS = false;
5556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
5566a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Output>::Locked output(mOutput);
5576a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        reachedEOS = output->mEncoderReachedEOS;
5586a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (!reachedEOS) {
5596a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("encoder (%s) reached EOS", mIsVideo ? "video" : "audio");
56072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // release all unread media buffers
5616a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            for (List<MediaBuffer*>::iterator it = output->mBufferQueue.begin();
5626a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                    it != output->mBufferQueue.end(); it++) {
56372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                (*it)->release();
56472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
5656a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mBufferQueue.clear();
5666a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mEncoderReachedEOS = true;
5676a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mErrorCode = err;
5686a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mCond.signal();
5696a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
5706a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            reachedEOS = true;
5716a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output.unlock();
5726a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            releaseEncoder();
57372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
57472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
5756a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
5766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (mStopping && reachedEOS) {
57716e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio");
5786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mPuller->stopSource();
5796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
58072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // posting reply to everyone that's waiting
5813f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        List<sp<AReplyToken>>::iterator it;
58272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        for (it = mStopReplyIDQueue.begin();
58372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                it != mStopReplyIDQueue.end(); it++) {
58472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(*it);
58572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
58672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.clear();
58772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = false;
5886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        ++mGeneration;
58972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
59072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
59172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
59272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::suspend() {
59372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
59472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder != NULL) {
59572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> params = new AMessage;
59672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        params->setInt32("drop-input-frames", true);
59772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mEncoder->setParameters(params);
59872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
59972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
60072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
60172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::resume(int64_t skipFramesBeforeUs) {
60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
60372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder != NULL) {
60472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> params = new AMessage;
60572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        params->setInt32("drop-input-frames", false);
60672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (skipFramesBeforeUs > 0) {
60772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            params->setInt64("skip-frames-before", skipFramesBeforeUs);
60872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
60972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mEncoder->setParameters(params);
61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() {
6146a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    MediaBuffer* mbuf = NULL;
6156a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (!mAvailEncoderInputIndices.empty() && mPuller->readBuffer(&mbuf)) {
61672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
61772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
61872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        int64_t timeUs = 0ll;
62072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags = 0;
62172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t size = 0;
62272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mbuf != NULL) {
62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
625d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim            timeUs += mInputBufferTimeOffsetUs;
62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // push decoding time for video, or drift time for audio
62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDecodingTimeQueue.push_back(timeUs);
63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME
63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mFirstSampleTimeUs < 0ll) {
63372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mFirstSampleTimeUs = timeUs;
63472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
63572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
63672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                int64_t driftTimeUs = 0;
63772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs)
63872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                        && driftTimeUs) {
63972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs;
64072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
64172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDriftTimeQueue.push_back(driftTimeUs);
64272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME
64372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
64472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6451099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            sp<ABuffer> inbuf;
6461099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf);
6471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (err != OK || inbuf == NULL) {
6481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->release();
6491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
6501099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
6511099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
6521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
65372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            size = mbuf->size();
65472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            memcpy(inbuf->data(), mbuf->data(), size);
65672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
65772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
65872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // video encoder will release MediaBuffer when done
65972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // with underlying data.
6601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                inbuf->setMediaBufferBase(mbuf);
66172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
66272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mbuf->release();
66372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
66472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
66572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            flags = MediaCodec::BUFFER_FLAG_EOS;
66672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
66872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err = mEncoder->queueInputBuffer(
66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                bufferIndex, 0, size, timeUs, flags);
67072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
67172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
67272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
67372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
67472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
67572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
67672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
67772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
67872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
67972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) {
68072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStopping) {
68172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGE("Failed to start while we're stopping");
68272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return INVALID_OPERATION;
68372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
68472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
68572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStarted) {
68672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio");
68772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
68872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            resume();
68972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
69072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mPuller != NULL);
69172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPuller->resume();
69272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
69372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
69472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
69572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio");
69772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = OK;
69972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
70072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
70172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        int64_t startTimeUs;
70272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!params || !params->findInt64(kKeyTime, &startTimeUs)) {
70372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            startTimeUs = -1ll;
70472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
70572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        resume(startTimeUs);
70672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    } else {
70772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mPuller != NULL);
708c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        sp<MetaData> meta = params;
709c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mSetEncoderFormat) {
710c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            if (meta == NULL) {
711c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                meta = new MetaData;
712c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            }
713c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyPixelFormat, mEncoderFormat);
714c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyColorSpace, mEncoderDataSpace);
715c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
716c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
7171d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector);
718c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        err = mPuller->start(meta.get(), notify);
71972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
72072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
72172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
72272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
72372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
72472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio");
72572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
72672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mStarted = true;
72772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
72872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
72972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
73072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
73172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
73272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPullerNotify:
73372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
7346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int32_t eos = 0;
7356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (msg->findInt32("eos", &eos) && eos) {
7366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("puller (%s) reached EOS", mIsVideo ? "video" : "audio");
73716e79115e497386eaf010af388627f94314a55a3Chong Zhang            signalEOS();
7386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            break;
73972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
74072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
74172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
7426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str());
74372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
74472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
74572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
74672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        feedEncoderInputBuffers();
74772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
74872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
74972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatEncoderActivity:
75072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
75172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
75272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
75372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
75472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        int32_t cbID;
7561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        CHECK(msg->findInt32("callbackID", &cbID));
7571099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        if (cbID == MediaCodec::CB_INPUT_AVAILABLE) {
7581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
7591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
7601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7611099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mAvailEncoderInputIndices.push_back(index);
7621099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            feedEncoderInputBuffers();
7631099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) {
7641099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
7651099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t offset;
7661099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t size;
7671099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int64_t timeUs;
7681099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t flags;
7691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
7711099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("offset", &offset));
7721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("size", &size));
7731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt64("timeUs", &timeUs));
7741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("flags", &flags));
7751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7761099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_EOS) {
7771099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mEncoder->releaseOutputBuffer(index);
7781099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
7791099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
7801099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
781f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
7821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            sp<ABuffer> outbuf;
7831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getOutputBuffer(index, &outbuf);
7841099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (err != OK || outbuf == NULL) {
7851099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
7861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
7871099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
788f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
7891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            MediaBuffer *mbuf = new MediaBuffer(outbuf->size());
7901099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            memcpy(mbuf->data(), outbuf->data(), outbuf->size());
79172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7921099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) {
7931099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                if (mIsVideo) {
7941099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t decodingTimeUs;
7951099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    if (mFlags & FLAG_USE_SURFACE_INPUT) {
796d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        // Time offset is not applied at
797d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        // feedEncoderInputBuffer() in surface input case.
798d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        timeUs += mInputBufferTimeOffsetUs;
7991099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // GraphicBufferSource is supposed to discard samples
8001099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // queued before start, and offset timeUs by start time
8011099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        CHECK_GE(timeUs, 0ll);
8021099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // TODO:
8031099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // Decoding time for surface source is unavailable,
8041099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // use presentation time for now. May need to move
8051099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // this logic into MediaCodec.
8061099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = timeUs;
8071099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    } else {
8081099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        CHECK(!mDecodingTimeQueue.empty());
8091099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = *(mDecodingTimeQueue.begin());
8101099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        mDecodingTimeQueue.erase(mDecodingTimeQueue.begin());
8111099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    }
8121099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
81372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8141099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64,
8151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, decodingTimeUs - timeUs);
8161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                } else {
8171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t driftTimeUs = 0;
8181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#if DEBUG_DRIFT_TIME
8191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    CHECK(!mDriftTimeQueue.empty());
8201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    driftTimeUs = *(mDriftTimeQueue.begin());
8211099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mDriftTimeQueue.erase(mDriftTimeQueue.begin());
8221099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs);
8231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#endif // DEBUG_DRIFT_TIME
8241099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64,
8251099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, driftTimeUs);
8261099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                }
8271099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt64(kKeyTime, timeUs);
8281099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            } else {
8291099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true);
8301099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
8321099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true);
8331099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8341099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mbuf->setObserver(this);
8351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mbuf->add_ref();
8361099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8371099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            {
8386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                Mutexed<Output>::Locked output(mOutput);
8396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                output->mBufferQueue.push_back(mbuf);
8406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                output->mCond.signal();
8411099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8421099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8431099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mEncoder->releaseOutputBuffer(index);
8441099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       } else if (cbID == MediaCodec::CB_ERROR) {
8451099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err;
8461099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("err", &err));
8471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            ALOGE("Encoder (%s) reported error : 0x%x",
8481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mIsVideo ? "video" : "audio", err);
8491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            signalEOS();
8501099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       }
8511099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       break;
85272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
85372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStart:
85472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
8553f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
85672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
85772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
85872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<RefBase> obj;
85972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->findObject("meta", &obj));
86072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        MetaData *params = static_cast<MetaData *>(obj.get());
86172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
86272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> response = new AMessage;
86372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->setInt32("err", onStart(params));
86472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->postReply(replyID);
86572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
86672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
86772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStop:
86872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
86916e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio");
87072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8713f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
87272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
87372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8746a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (mOutput.lock()->mEncoderReachedEOS) {
87572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // if we already reached EOS, reply and return now
87616e79115e497386eaf010af388627f94314a55a3Chong Zhang            ALOGI("encoder (%s) already stopped",
87772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mIsVideo ? "video" : "audio");
87872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(replyID);
87972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
88072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
88172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
88272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.push_back(replyID);
88372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mStopping) {
88472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // nothing to do if we're already stopping, reply will be posted
88572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // to all when we're stopped.
88672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
88772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
88872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
88972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = true;
89072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
89172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // if using surface, signal source EOS and wait for EOS to come back.
8926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // otherwise, stop puller (which also clears the input buffer queue)
8936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // and wait for the EOS message. We cannot call source->stop() because
8946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // the encoder may still be processing input buffers.
89572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
89672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mEncoder->signalEndOfInputStream();
89772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
8986a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mPuller->stop();
89972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
9006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
9016a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // complete stop even if encoder/puller stalled
9026a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        sp<AMessage> timeoutMsg = new AMessage(kWhatStopStalled, mReflector);
9036a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        timeoutMsg->setInt32("generation", mGeneration);
9046a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        timeoutMsg->post(kStopTimeoutUs);
90572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
90672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
9076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
9086a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    case kWhatStopStalled:
9096a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
9106a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int32_t generation;
9116a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        CHECK(msg->findInt32("generation", &generation));
9126a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (generation != mGeneration) {
9136a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar             break;
9146a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        }
9156a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
9166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
9176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("source (%s) stopping", mIsVideo ? "video" : "audio");
9186a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mPuller->stopSource();
9196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
9206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        }
9216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        signalEOS();
9226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
9236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
92472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPause:
92572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
926d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        if (mFlags & FLAG_USE_SURFACE_INPUT) {
92772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            suspend();
92872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
92972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mPuller != NULL);
93072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPuller->pause();
93172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
93272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
93372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
934d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    case kWhatSetInputBufferTimeOffset:
935d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    {
936d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AReplyToken> replyID;
937d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->senderAwaitsResponse(&replyID));
938d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
939d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs));
940d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
941d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AMessage> response = new AMessage;
942d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        response->postReply(replyID);
943d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        break;
944d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    }
94572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    default:
94672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        TRESPASS();
94772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
94872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
94972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
95072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android
951