MediaCodecSource.cpp revision 72e9ab92e0dbee8d19ae2ec92ecd0a172b231b44
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
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();
5772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
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,
6972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    };
7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaSource> mSource;
7272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> mNotify;
7372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<ALooper> mLooper;
7472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mIsAudio;
756a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    struct Queue {
776a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Queue()
786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            : mReadPendingSince(0),
796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar              mPaused(false),
806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar              mPulling(false) { }
816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int64_t mReadPendingSince;
826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mPaused;
836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool mPulling;
846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Vector<MediaBuffer *> mReadBuffers;
856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        void flush();
876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // if queue is empty, return false and set *|buffer| to NULL . Otherwise, pop
8872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        // buffer from front of the queue, place it into *|buffer| and return true.
896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        bool readBuffer(MediaBuffer **buffer);
9072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        // add a buffer to the back of the queue
916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        void pushBuffer(MediaBuffer *mbuf);
926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    };
936a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue> mQueue;
9472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
9672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void schedulePull();
9772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void handleEOS();
9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(Puller);
10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang};
10172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10272cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source)
10372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mSource(source),
10472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mLooper(new ALooper()),
1056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mIsAudio(false)
1066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar{
10772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MetaData> meta = source->getFormat();
10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    const char *mime;
10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(meta->findCString(kKeyMIMEType, &mime));
11072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mIsAudio = !strncasecmp(mime, "audio/", 6);
11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->setName("pull_looper");
11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
11572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11672cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() {
11772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(id());
11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->stop();
11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
12072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::pushBuffer(MediaBuffer *mbuf) {
1226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    mReadBuffers.push_back(mbuf);
1236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::Queue::readBuffer(MediaBuffer **mbuf) {
1266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (mReadBuffers.empty()) {
1276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        *mbuf = NULL;
1286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        return false;
1296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    *mbuf = *mReadBuffers.begin();
1316a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    mReadBuffers.erase(mReadBuffers.begin());
1326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return true;
1336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::Queue::flush() {
1366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    MediaBuffer *mbuf;
1376a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (readBuffer(&mbuf)) {
1386a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // there are no null buffers in the queue
1396a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mbuf->release();
1406a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1416a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1426a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
1436a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarbool MediaCodecSource::Puller::readBuffer(MediaBuffer **mbuf) {
1446a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
1456a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return queue->readBuffer(mbuf);
1466a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
1476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
14872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError(
14972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
15072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
15172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
15272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
15472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
15872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
16372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1646a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta, const sp<AMessage> &notify) {
16572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGV("puller (%s) start", mIsAudio ? "audio" : "video");
16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->start(
16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* runOnCallingThread */,
16872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* canCallJava */,
16972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            PRIORITY_AUDIO);
17072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(this);
17172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mNotify = notify;
17272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
17472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", meta);
17572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
17772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
17816e79115e497386eaf010af388627f94314a55a3Chong Zhangvoid MediaCodecSource::Puller::stop() {
1796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool interrupt = false;
1806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
1816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // mark stopping before actually reaching kWhatStop on the looper, so the pulling will
1826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // stop.
1836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Queue>::Locked queue(mQueue);
1846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        queue->mPulling = false;
1856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        interrupt = queue->mReadPendingSince && (queue->mReadPendingSince < ALooper::GetNowUs() - 1000000);
1866a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        queue->flush(); // flush any unprocessed pulled buffers
1876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
18816e79115e497386eaf010af388627f94314a55a3Chong Zhang
1896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (interrupt) {
19072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar        interruptSource();
1916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
1926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
19316e79115e497386eaf010af388627f94314a55a3Chong Zhang
19472e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnarvoid MediaCodecSource::Puller::interruptSource() {
19572e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    // call source->stop if read has been pending for over a second
19672e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    // We have to call this outside the looper as looper is pending on the read.
19772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    mSource->stop();
19872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar}
19972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
2006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnarvoid MediaCodecSource::Puller::stopSource() {
20172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
20272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar    (void)postSynchronouslyAndReturnError(msg);
20372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
20472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
20572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() {
2066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
2076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    queue->mPaused = true;
20872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
20972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() {
2116a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Queue>::Locked queue(mQueue);
2126a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    queue->mPaused = false;
21372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
21472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() {
2166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    (new AMessage(kWhatPull, this))->post();
21772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
21872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() {
2206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video");
2216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    sp<AMessage> msg = mNotify->dup();
2226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    msg->setInt32("eos", 1);
2236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    msg->post();
22472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
22772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
22872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStart:
22972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
23072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<RefBase> obj;
23172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->findObject("meta", &obj));
23272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            {
2346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                Mutexed<Queue>::Locked queue(mQueue);
2356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                queue->mPulling = true;
2366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
23772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->start(static_cast<MetaData *>(obj.get()));
23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
24072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (err == OK) {
24172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                schedulePull();
24272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
24372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
24472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<AMessage> response = new AMessage;
24572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->setInt32("err", err);
24672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2473f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
24872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
24972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->postReply(replyID);
25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStop:
25472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
2556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mSource->stop();
25672e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
25772e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            sp<AMessage> response = new AMessage;
25872e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            response->setInt32("err", OK);
25972e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar
26072e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            sp<AReplyToken> replyID;
26172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
26272e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            response->postReply(replyID);
26372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
26472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
26572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
26672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatPull:
26772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
2686a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            Mutexed<Queue>::Locked queue(mQueue);
2696a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue->mReadPendingSince = ALooper::GetNowUs();
2706a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (!queue->mPulling) {
2716a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                handleEOS();
27272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                break;
27372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
27472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2756a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.unlock();
2766a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            MediaBuffer *mbuf = NULL;
27772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->read(&mbuf);
2786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.lock();
27972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue->mReadPendingSince = 0;
2816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            // if we need to discard buffer
2826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (!queue->mPulling || queue->mPaused || err != OK) {
2836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                if (mbuf != NULL) {
28472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf->release();
28572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf = NULL;
28672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
2876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                if (queue->mPulling && err == OK) {
2886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                    msg->post(); // if simply paused, keep pulling source
2896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                } else if (err == ERROR_END_OF_STREAM) {
29072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGV("stream ended, mbuf %p", mbuf);
2916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                } else if (err != OK) {
29272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGE("error %d reading stream.", err);
29372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
2946a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
29572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
2966a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (mbuf != NULL) {
2976a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                queue->pushBuffer(mbuf);
29872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
29972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3006a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            queue.unlock();
30172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3026a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            if (mbuf != NULL) {
3036a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                mNotify->post();
3046a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                msg->post();
3056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            } else {
3066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                handleEOS();
3076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            }
30872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
30972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
31072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
31172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        default:
31272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            TRESPASS();
31372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
31472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
31572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
3166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos MolnarMediaCodecSource::Output::Output()
3176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    : mEncoderReachedEOS(false),
3186a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mErrorCode(OK) {
3196a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar}
3206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
32172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static
32272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create(
32372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
32472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &format,
32572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
326e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        const sp<IGraphicBufferConsumer> &consumer,
32772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags) {
32872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaCodecSource> mediaSource =
329e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            new MediaCodecSource(looper, format, source, consumer, flags);
33072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
33172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mediaSource->init() == OK) {
33272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return mediaSource;
33372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return NULL;
33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
33672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
337d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kimvoid MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
338d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector);
339d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    msg->setInt64("time-offset-us", timeOffsetUs);
340d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    postSynchronouslyAndReturnError(msg);
341d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim}
342d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
34372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) {
3441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, mReflector);
34572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", params);
34672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
34772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
34872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() {
3501d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, mReflector);
3516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return postSynchronouslyAndReturnError(msg);
35272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
35372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
35472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::pause() {
3551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatPause, mReflector))->post();
35672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
35772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
35872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
35972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() {
36072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
36172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return mGraphicBufferProducer;
36272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
36372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
36484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaCodecSource::read(
36584333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        MediaBuffer** buffer, const ReadOptions* /* options */) {
3666a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    Mutexed<Output>::Locked output(mOutput);
36772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
36872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    *buffer = NULL;
3696a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (output->mBufferQueue.size() == 0 && !output->mEncoderReachedEOS) {
3706a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output.waitForCondition(output->mCond);
37172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
3726a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (!output->mEncoderReachedEOS) {
3736a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        *buffer = *output->mBufferQueue.begin();
3746a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mBufferQueue.erase(output->mBufferQueue.begin());
37572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
37672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
3776a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    return output->mErrorCode;
37872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
37972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) {
38172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->setObserver(0);
38272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->release();
38372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
38472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
38572cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource(
38672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
38772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &outputFormat,
38872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
389e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        const sp<IGraphicBufferConsumer> &consumer,
39072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags)
39172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mLooper(looper),
39272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mOutputFormat(outputFormat),
39372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mMeta(new MetaData),
39472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFlags(flags),
39572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mIsVideo(false),
39672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStarted(false),
39772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStopping(false),
39872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mDoMoreWorkPending(false),
399c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mSetEncoderFormat(false),
400c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderFormat(0),
401c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderDataSpace(0),
402e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang      mGraphicBufferConsumer(consumer),
403d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim      mInputBufferTimeOffsetUs(0),
40472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFirstSampleTimeUs(-1ll),
4056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar      mGeneration(0) {
40672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mLooper != NULL);
40772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
40872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString mime;
40972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &mime));
41072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!strncasecmp("video/", mime.c_str(), 6)) {
41272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mIsVideo = true;
41372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
41472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
41672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mPuller = new Puller(source);
41772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
41872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
41972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42072cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() {
42172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    releaseEncoder();
42272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->stop();
42472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(mReflector->id());
42572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
42672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() {
42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = initEncoder();
42972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        releaseEncoder();
43272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
43372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
43572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
43672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() {
43872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mReflector = new AHandlerReflector<MediaCodecSource>(this);
43972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(mReflector);
44072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
44172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper = new ALooper;
44272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->setName("codec_looper");
44372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->start();
44472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
44572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_METADATA_INPUT) {
44672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputFormat->setInt32("store-metadata-in-buffers", 1);
44772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
44872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
44972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
45072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputFormat->setInt32("create-input-buffers-suspended", 1);
45172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
45272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
45372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString outputMIME;
45472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &outputMIME));
45572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
45616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    Vector<AString> matchingCodecs;
45716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    MediaCodecList::findMatchingCodecs(
45816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            outputMIME.c_str(), true /* encoder */,
45916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            ((mFlags & FLAG_PREFER_SOFTWARE_CODEC) ? MediaCodecList::kPreferSoftwareCodecs : 0),
46016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            &matchingCodecs);
46172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    status_t err = NO_INIT;
46316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    for (size_t ix = 0; ix < matchingCodecs.size(); ++ix) {
46416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = MediaCodec::CreateByComponentName(
46516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                mCodecLooper, matchingCodecs[ix]);
46616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
46716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (mEncoder == NULL) {
46816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            continue;
46916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
47016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
47116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
47272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector);
47416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->setCallback(mEncoderActivityNotify);
47572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
47616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        err = mEncoder->configure(
47716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    mOutputFormat,
47816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* nativeWindow */,
47916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* crypto */,
48016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    MediaCodec::CONFIGURE_FLAG_ENCODE);
481421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
48216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (err == OK) {
48316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            break;
48416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
48516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->release();
48616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = NULL;
48716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    }
48872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
49072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
49172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
49272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->getOutputFormat(&mOutputFormat);
49472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    convertMessageToMetaData(mOutputFormat, mMeta);
49572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
49772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mIsVideo);
49872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
499e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        if (mGraphicBufferConsumer != NULL) {
500e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // When using persistent surface, we are only interested in the
501e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // consumer, but have to use PersistentSurface as a wrapper to
502e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // pass consumer over messages (similar to BufferProducerWrapper)
5038f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            err = mEncoder->setInputSurface(
504e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang                    new PersistentSurface(NULL, mGraphicBufferConsumer));
505e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        } else {
506e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            err = mEncoder->createInputSurface(&mGraphicBufferProducer);
507e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        }
50872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
50972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
51072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
51172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
51272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
51372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
514c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    sp<AMessage> inputFormat;
515c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    int32_t usingSwReadOften;
516c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    mSetEncoderFormat = false;
517c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    if (mEncoder->getInputFormat(&inputFormat) == OK
518c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            && inputFormat->findInt32("using-sw-read-often", &usingSwReadOften)
519c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            && usingSwReadOften) {
520c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        // this is a SW encoder; signal source to allocate SW readable buffers
521c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mSetEncoderFormat = true;
522c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mEncoderFormat = kDefaultSwVideoEncoderFormat;
523c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mEncoderDataSpace = kDefaultSwVideoEncoderDataSpace;
524c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
525c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
5261099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan    err = mEncoder->start();
52772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
52972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
53072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
53172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
5336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Output>::Locked output(mOutput);
5346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mEncoderReachedEOS = false;
5356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        output->mErrorCode = OK;
5366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
53772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
53872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
53972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
54072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
54172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() {
54272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder == NULL) {
54372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return;
54472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
54572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
54672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->release();
54772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder.clear();
54872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
54972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
55072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError(
55172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
55272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
55372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
55472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
55572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
55672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
55772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
55872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
55972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
56072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
56172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
56272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
56372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
56472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
56572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
56672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) {
5676a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    bool reachedEOS = false;
5686a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
5696a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        Mutexed<Output>::Locked output(mOutput);
5706a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        reachedEOS = output->mEncoderReachedEOS;
5716a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (!reachedEOS) {
5726a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("encoder (%s) reached EOS", mIsVideo ? "video" : "audio");
57372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // release all unread media buffers
5746a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            for (List<MediaBuffer*>::iterator it = output->mBufferQueue.begin();
5756a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                    it != output->mBufferQueue.end(); it++) {
57672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                (*it)->release();
57772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
5786a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mBufferQueue.clear();
5796a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mEncoderReachedEOS = true;
5806a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mErrorCode = err;
5816a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output->mCond.signal();
5826a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
5836a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            reachedEOS = true;
5846a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            output.unlock();
5856a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            releaseEncoder();
58672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
58772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
5886a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
5896a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    if (mStopping && reachedEOS) {
59016e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio");
5916a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        mPuller->stopSource();
5926a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
59372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // posting reply to everyone that's waiting
5943f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        List<sp<AReplyToken>>::iterator it;
59572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        for (it = mStopReplyIDQueue.begin();
59672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                it != mStopReplyIDQueue.end(); it++) {
59772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(*it);
59872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
59972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.clear();
60072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = false;
6016a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        ++mGeneration;
60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
60372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
60472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
60572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::suspend() {
60672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
60772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder != NULL) {
60872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> params = new AMessage;
60972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        params->setInt32("drop-input-frames", true);
61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mEncoder->setParameters(params);
61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
61472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::resume(int64_t skipFramesBeforeUs) {
61572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
61672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder != NULL) {
61772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> params = new AMessage;
61872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        params->setInt32("drop-input-frames", false);
61972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (skipFramesBeforeUs > 0) {
62072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            params->setInt64("skip-frames-before", skipFramesBeforeUs);
62172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
62272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mEncoder->setParameters(params);
62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
62472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() {
6276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    MediaBuffer* mbuf = NULL;
6286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    while (!mAvailEncoderInputIndices.empty() && mPuller->readBuffer(&mbuf)) {
62972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        int64_t timeUs = 0ll;
63372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags = 0;
63472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t size = 0;
63572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
63672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mbuf != NULL) {
63772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
638d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim            timeUs += mInputBufferTimeOffsetUs;
63972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
64072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // push decoding time for video, or drift time for audio
64172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
64272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDecodingTimeQueue.push_back(timeUs);
64372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
64472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME
64572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mFirstSampleTimeUs < 0ll) {
64672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mFirstSampleTimeUs = timeUs;
64772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
64872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
64972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                int64_t driftTimeUs = 0;
65072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs)
65172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                        && driftTimeUs) {
65272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs;
65372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
65472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDriftTimeQueue.push_back(driftTimeUs);
65572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME
65672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
65772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            sp<ABuffer> inbuf;
6591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf);
6601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (err != OK || inbuf == NULL) {
6611099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->release();
6621099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
6631099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
6641099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
6651099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
66672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            size = mbuf->size();
66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6681099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            memcpy(inbuf->data(), mbuf->data(), size);
66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
67072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
67172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // video encoder will release MediaBuffer when done
67272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // with underlying data.
6731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                inbuf->setMediaBufferBase(mbuf);
67472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
67572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mbuf->release();
67672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
67772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
67872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            flags = MediaCodec::BUFFER_FLAG_EOS;
67972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
68072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
68172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err = mEncoder->queueInputBuffer(
68272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                bufferIndex, 0, size, timeUs, flags);
68372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
68472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
68572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
68672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
68772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
68872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
68972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
69072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
69172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) {
69372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStopping) {
69472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGE("Failed to start while we're stopping");
69572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return INVALID_OPERATION;
69672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
69772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStarted) {
69972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio");
70072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
70172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            resume();
70272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
70372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mPuller != NULL);
70472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPuller->resume();
70572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
70672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
70772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
70872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
70972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio");
71072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
71172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = OK;
71272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
71372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
71472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        int64_t startTimeUs;
71572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!params || !params->findInt64(kKeyTime, &startTimeUs)) {
71672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            startTimeUs = -1ll;
71772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
71872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        resume(startTimeUs);
71972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    } else {
72072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mPuller != NULL);
721c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        sp<MetaData> meta = params;
722c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mSetEncoderFormat) {
723c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            if (meta == NULL) {
724c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                meta = new MetaData;
725c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            }
726c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyPixelFormat, mEncoderFormat);
727c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyColorSpace, mEncoderDataSpace);
728c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
729c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
7301d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector);
731c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        err = mPuller->start(meta.get(), notify);
73272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
73372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
73472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
73572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
73672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
73772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio");
73872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
73972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mStarted = true;
74072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
74172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
74272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
74372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
74472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
74572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPullerNotify:
74672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
7476a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int32_t eos = 0;
7486a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (msg->findInt32("eos", &eos) && eos) {
7496a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("puller (%s) reached EOS", mIsVideo ? "video" : "audio");
75016e79115e497386eaf010af388627f94314a55a3Chong Zhang            signalEOS();
7516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            break;
75272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
75372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
75472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
7556a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("got msg '%s' after encoder shutdown.", msg->debugString().c_str());
75672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
75772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
75872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
75972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        feedEncoderInputBuffers();
76072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
76172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
76272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatEncoderActivity:
76372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
76472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
76572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
76672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
76772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7681099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        int32_t cbID;
7691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        CHECK(msg->findInt32("callbackID", &cbID));
7701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        if (cbID == MediaCodec::CB_INPUT_AVAILABLE) {
7711099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
7721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
7731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mAvailEncoderInputIndices.push_back(index);
7751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            feedEncoderInputBuffers();
7761099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) {
7771099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
7781099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t offset;
7791099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t size;
7801099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int64_t timeUs;
7811099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t flags;
7821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
7841099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("offset", &offset));
7851099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("size", &size));
7861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt64("timeUs", &timeUs));
7871099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("flags", &flags));
7881099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_EOS) {
7901099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mEncoder->releaseOutputBuffer(index);
7911099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
7921099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
7931099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
794f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
7951099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            sp<ABuffer> outbuf;
7961099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getOutputBuffer(index, &outbuf);
7971099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (err != OK || outbuf == NULL) {
7981099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
7991099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
8001099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
801f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
8021099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            MediaBuffer *mbuf = new MediaBuffer(outbuf->size());
8031099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            memcpy(mbuf->data(), outbuf->data(), outbuf->size());
80472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8051099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) {
8061099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                if (mIsVideo) {
8071099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t decodingTimeUs;
8081099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    if (mFlags & FLAG_USE_SURFACE_INPUT) {
809d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        // Time offset is not applied at
810d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        // feedEncoderInputBuffer() in surface input case.
811d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        timeUs += mInputBufferTimeOffsetUs;
8121099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // GraphicBufferSource is supposed to discard samples
8131099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // queued before start, and offset timeUs by start time
8141099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        CHECK_GE(timeUs, 0ll);
8151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // TODO:
8161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // Decoding time for surface source is unavailable,
8171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // use presentation time for now. May need to move
8181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // this logic into MediaCodec.
8191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = timeUs;
8201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    } else {
8211099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        CHECK(!mDecodingTimeQueue.empty());
8221099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = *(mDecodingTimeQueue.begin());
8231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        mDecodingTimeQueue.erase(mDecodingTimeQueue.begin());
8241099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    }
8251099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
82672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8271099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64,
8281099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, decodingTimeUs - timeUs);
8291099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                } else {
8301099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t driftTimeUs = 0;
8311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#if DEBUG_DRIFT_TIME
8321099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    CHECK(!mDriftTimeQueue.empty());
8331099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    driftTimeUs = *(mDriftTimeQueue.begin());
8341099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mDriftTimeQueue.erase(mDriftTimeQueue.begin());
8351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs);
8361099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#endif // DEBUG_DRIFT_TIME
8371099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64,
8381099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, driftTimeUs);
8391099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                }
8401099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt64(kKeyTime, timeUs);
8411099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            } else {
8421099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true);
8431099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8441099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
8451099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true);
8461099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mbuf->setObserver(this);
8481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mbuf->add_ref();
8491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8501099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            {
8516a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                Mutexed<Output>::Locked output(mOutput);
8526a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                output->mBufferQueue.push_back(mbuf);
8536a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar                output->mCond.signal();
8541099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mEncoder->releaseOutputBuffer(index);
8571099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       } else if (cbID == MediaCodec::CB_ERROR) {
8581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err;
8591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("err", &err));
8601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            ALOGE("Encoder (%s) reported error : 0x%x",
8611099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mIsVideo ? "video" : "audio", err);
8621099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            signalEOS();
8631099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       }
8641099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       break;
86572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
86672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStart:
86772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
8683f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
86972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
87072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
87172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<RefBase> obj;
87272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->findObject("meta", &obj));
87372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        MetaData *params = static_cast<MetaData *>(obj.get());
87472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
87572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> response = new AMessage;
87672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->setInt32("err", onStart(params));
87772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->postReply(replyID);
87872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
87972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
88072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStop:
88172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
88216e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio");
88372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8843f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
88572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
88672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8876a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (mOutput.lock()->mEncoderReachedEOS) {
88872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // if we already reached EOS, reply and return now
88916e79115e497386eaf010af388627f94314a55a3Chong Zhang            ALOGI("encoder (%s) already stopped",
89072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mIsVideo ? "video" : "audio");
89172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(replyID);
89272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
89372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
89472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
89572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.push_back(replyID);
89672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mStopping) {
89772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // nothing to do if we're already stopping, reply will be posted
89872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // to all when we're stopped.
89972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
90072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
90172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
90272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = true;
90372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
90472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // if using surface, signal source EOS and wait for EOS to come back.
9056a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // otherwise, stop puller (which also clears the input buffer queue)
9066a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // and wait for the EOS message. We cannot call source->stop() because
9076a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // the encoder may still be processing input buffers.
90872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
90972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mEncoder->signalEndOfInputStream();
91072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
9116a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            mPuller->stop();
91272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
9136a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
9146a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        // complete stop even if encoder/puller stalled
9156a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        sp<AMessage> timeoutMsg = new AMessage(kWhatStopStalled, mReflector);
9166a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        timeoutMsg->setInt32("generation", mGeneration);
9176a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        timeoutMsg->post(kStopTimeoutUs);
91872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
91972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
9206a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
9216a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    case kWhatStopStalled:
9226a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    {
9236a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        int32_t generation;
9246a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        CHECK(msg->findInt32("generation", &generation));
9256a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (generation != mGeneration) {
9266a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar             break;
9276a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        }
9286a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
9296a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
9306a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("source (%s) stopping", mIsVideo ? "video" : "audio");
93172e9ab92e0dbee8d19ae2ec92ecd0a172b231b44Lajos Molnar            mPuller->interruptSource();
9326a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar            ALOGV("source (%s) stopped", mIsVideo ? "video" : "audio");
9336a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        }
9346a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar        signalEOS();
9356a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar    }
9366a3a56fbcd6c01c3895f14e43858971b0edca9b2Lajos Molnar
93772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPause:
93872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
939d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        if (mFlags & FLAG_USE_SURFACE_INPUT) {
94072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            suspend();
94172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
94272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mPuller != NULL);
94372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPuller->pause();
94472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
94572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
94672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
947d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    case kWhatSetInputBufferTimeOffset:
948d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    {
949d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AReplyToken> replyID;
950d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->senderAwaitsResponse(&replyID));
951d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
952d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs));
953d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
954d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AMessage> response = new AMessage;
955d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        response->postReply(replyID);
956d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        break;
957d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    }
95872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    default:
95972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        TRESPASS();
96072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
96172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
96272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
96372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android
964