MediaCodecSource.cpp revision 16fcc47c113e63efa69f5af5decf1ad46ec653a9
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
4672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstruct MediaCodecSource::Puller : public AHandler {
4772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    Puller(const sp<MediaSource> &source);
4872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
4972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t start(const sp<MetaData> &meta, const sp<AMessage> &notify);
5016e79115e497386eaf010af388627f94314a55a3Chong Zhang    void stop();
5172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void pause();
5372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void resume();
5472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprotected:
5672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual void onMessageReceived(const sp<AMessage> &msg);
5772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    virtual ~Puller();
5872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
5972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangprivate:
6072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    enum {
6172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStart = 'msta',
6272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatStop,
6372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatPull,
6472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatPause,
6572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        kWhatResume,
6672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    };
6772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaSource> mSource;
6972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> mNotify;
7072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<ALooper> mLooper;
7172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    int32_t mPullGeneration;
7272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mIsAudio;
7372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mPaused;
7472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    bool mReachedEOS;
7572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t postSynchronouslyAndReturnError(const sp<AMessage> &msg);
7772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void schedulePull();
7872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    void handleEOS();
7972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(Puller);
8172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang};
8272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8372cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::Puller(const sp<MediaSource> &source)
8472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mSource(source),
8572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mLooper(new ALooper()),
8672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mPullGeneration(0),
8772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mIsAudio(false),
8872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mPaused(false),
8972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mReachedEOS(false) {
9072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MetaData> meta = source->getFormat();
9172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    const char *mime;
9272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(meta->findCString(kKeyMIMEType, &mime));
9372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mIsAudio = !strncasecmp(mime, "audio/", 6);
9572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->setName("pull_looper");
9772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
9872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
9972cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::Puller::~Puller() {
10072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(id());
10172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->stop();
10272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
10372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::postSynchronouslyAndReturnError(
10572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
10672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
10772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
10872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
10972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
11072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
11172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
11272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
11472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
11572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
11672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
11772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
11872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
11972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
12072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::Puller::start(const sp<MetaData> &meta,
12172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &notify) {
12272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGV("puller (%s) start", mIsAudio ? "audio" : "video");
12372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->start(
12472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* runOnCallingThread */,
12572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            false /* canCallJava */,
12672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            PRIORITY_AUDIO);
12772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(this);
12872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mNotify = notify;
12972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1301d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
13172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", meta);
13272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
13372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
13472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
13516e79115e497386eaf010af388627f94314a55a3Chong Zhangvoid MediaCodecSource::Puller::stop() {
13616e79115e497386eaf010af388627f94314a55a3Chong Zhang    // Stop source from caller's thread instead of puller's looper.
13716e79115e497386eaf010af388627f94314a55a3Chong Zhang    // mSource->stop() is thread-safe, doing it outside the puller's
13816e79115e497386eaf010af388627f94314a55a3Chong Zhang    // looper allows us to at least stop if source gets stuck.
13916e79115e497386eaf010af388627f94314a55a3Chong Zhang    // If source gets stuck in read(), the looper would never
14016e79115e497386eaf010af388627f94314a55a3Chong Zhang    // be able to process the stop(), which could lead to ANR.
14116e79115e497386eaf010af388627f94314a55a3Chong Zhang
14216e79115e497386eaf010af388627f94314a55a3Chong Zhang    ALOGV("source (%s) stopping", mIsAudio ? "audio" : "video");
14316e79115e497386eaf010af388627f94314a55a3Chong Zhang    mSource->stop();
14416e79115e497386eaf010af388627f94314a55a3Chong Zhang    ALOGV("source (%s) stopped", mIsAudio ? "audio" : "video");
14516e79115e497386eaf010af388627f94314a55a3Chong Zhang
1461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatStop, this))->post();
14772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
14872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
14972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::pause() {
1501d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatPause, this))->post();
15172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
15272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::resume() {
1541d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatResume, this))->post();
15572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
15672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
15772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::schedulePull() {
1581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatPull, this);
15972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setInt32("generation", mPullGeneration);
16072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->post();
16172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
16272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
16372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::handleEOS() {
16472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!mReachedEOS) {
16572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGV("puller (%s) posting EOS", mIsAudio ? "audio" : "video");
16672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mReachedEOS = true;
16772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> notify = mNotify->dup();
16872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        notify->setPointer("accessUnit", NULL);
16972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        notify->post();
17072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
17172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
17272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
17372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::Puller::onMessageReceived(const sp<AMessage> &msg) {
17472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
17572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStart:
17672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
17772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<RefBase> obj;
17872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->findObject("meta", &obj));
17972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
18072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mReachedEOS = false;
18172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
18272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->start(static_cast<MetaData *>(obj.get()));
18372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
18472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (err == OK) {
18572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                schedulePull();
18672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
18772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
18872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            sp<AMessage> response = new AMessage;
18972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->setInt32("err", err);
19072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
1913f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
19372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            response->postReply(replyID);
19472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
19572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
19672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
19772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatStop:
19872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
19972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ++mPullGeneration;
20072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
20172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            handleEOS();
20272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
20372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
20472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
20572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatPull:
20672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
20772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            int32_t generation;
20872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(msg->findInt32("generation", &generation));
20972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (generation != mPullGeneration) {
21172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                break;
21272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
21372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            MediaBuffer *mbuf;
21572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            status_t err = mSource->read(&mbuf);
21672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
21772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mPaused) {
21872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (err == OK) {
21972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf->release();
22072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mbuf = NULL;
22172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
22272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                msg->post();
22472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                break;
22572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
22672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
22772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (err != OK) {
22872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (err == ERROR_END_OF_STREAM) {
22972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGV("stream ended, mbuf %p", mbuf);
23072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                } else {
23172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    ALOGE("error %d reading stream.", err);
23272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
23372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                handleEOS();
23472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
23572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                sp<AMessage> notify = mNotify->dup();
23672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
23772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                notify->setPointer("accessUnit", mbuf);
23872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                notify->post();
23972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
24072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                msg->post();
24172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
24272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
24372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
24472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
24572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatPause:
24672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
24772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPaused = true;
24872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
24972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
25072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
25172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        case kWhatResume:
25272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
25372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPaused = false;
25472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
25572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
25672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
25772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        default:
25872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            TRESPASS();
25972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
26072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
26172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
26272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang// static
26372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<MediaCodecSource> MediaCodecSource::Create(
26472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
26572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &format,
26672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
267e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        const sp<IGraphicBufferConsumer> &consumer,
26872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags) {
26972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<MediaCodecSource> mediaSource =
270e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            new MediaCodecSource(looper, format, source, consumer, flags);
27172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
27272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mediaSource->init() == OK) {
27372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return mediaSource;
27472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
27572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return NULL;
27672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
27772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
278d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kimvoid MediaCodecSource::setInputBufferTimeOffset(int64_t timeOffsetUs) {
279d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    sp<AMessage> msg = new AMessage(kWhatSetInputBufferTimeOffset, mReflector);
280d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    msg->setInt64("time-offset-us", timeOffsetUs);
281d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    postSynchronouslyAndReturnError(msg);
282d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim}
283d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
28472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::start(MetaData* params) {
2851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, mReflector);
28672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    msg->setObject("meta", params);
28772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return postSynchronouslyAndReturnError(msg);
28872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
28972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
29072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::stop() {
2911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, mReflector);
29216e79115e497386eaf010af388627f94314a55a3Chong Zhang    status_t err = postSynchronouslyAndReturnError(msg);
29316e79115e497386eaf010af388627f94314a55a3Chong Zhang
29416e79115e497386eaf010af388627f94314a55a3Chong Zhang    // mPuller->stop() needs to be done outside MediaCodecSource's looper,
29516e79115e497386eaf010af388627f94314a55a3Chong Zhang    // as it contains a synchronous call to stop the underlying MediaSource,
29616e79115e497386eaf010af388627f94314a55a3Chong Zhang    // which often waits for all outstanding MediaBuffers to return, but
29716e79115e497386eaf010af388627f94314a55a3Chong Zhang    // MediaBuffers are only returned when MediaCodecSource looper gets
29816e79115e497386eaf010af388627f94314a55a3Chong Zhang    // to process them.
29916e79115e497386eaf010af388627f94314a55a3Chong Zhang
30016e79115e497386eaf010af388627f94314a55a3Chong Zhang    if (mPuller != NULL) {
30116e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("puller (%s) stopping", mIsVideo ? "video" : "audio");
30216e79115e497386eaf010af388627f94314a55a3Chong Zhang        mPuller->stop();
30316e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("puller (%s) stopped", mIsVideo ? "video" : "audio");
30416e79115e497386eaf010af388627f94314a55a3Chong Zhang    }
30516e79115e497386eaf010af388627f94314a55a3Chong Zhang
30616e79115e497386eaf010af388627f94314a55a3Chong Zhang    return err;
30772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
30872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
30972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::pause() {
3101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatPause, mReflector))->post();
31172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
31272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
31372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
31472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangsp<IGraphicBufferProducer> MediaCodecSource::getGraphicBufferProducer() {
31572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
31672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return mGraphicBufferProducer;
31772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
31872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
31984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t MediaCodecSource::read(
32084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        MediaBuffer** buffer, const ReadOptions* /* options */) {
32172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    Mutex::Autolock autolock(mOutputBufferLock);
32272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
32372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    *buffer = NULL;
32416e79115e497386eaf010af388627f94314a55a3Chong Zhang    while (mOutputBufferQueue.size() == 0 && !mEncoderReachedEOS) {
32572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputBufferCond.wait(mOutputBufferLock);
32672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
32716e79115e497386eaf010af388627f94314a55a3Chong Zhang    if (!mEncoderReachedEOS) {
32872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        *buffer = *mOutputBufferQueue.begin();
32972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputBufferQueue.erase(mOutputBufferQueue.begin());
33072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
33172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
33272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return mErrorCode;
33372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
33472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
33572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalBufferReturned(MediaBuffer *buffer) {
33672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->setObserver(0);
33772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    buffer->release();
33872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
33972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
34072cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::MediaCodecSource(
34172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<ALooper> &looper,
34272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &outputFormat,
34372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<MediaSource> &source,
344e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        const sp<IGraphicBufferConsumer> &consumer,
34572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags)
34672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    : mLooper(looper),
34772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mOutputFormat(outputFormat),
34872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mMeta(new MetaData),
34972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFlags(flags),
35072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mIsVideo(false),
35172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStarted(false),
35272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mStopping(false),
35372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mDoMoreWorkPending(false),
354c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mSetEncoderFormat(false),
355c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderFormat(0),
356c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar      mEncoderDataSpace(0),
357e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang      mGraphicBufferConsumer(consumer),
358d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim      mInputBufferTimeOffsetUs(0),
35972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mFirstSampleTimeUs(-1ll),
36016e79115e497386eaf010af388627f94314a55a3Chong Zhang      mEncoderReachedEOS(false),
36172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang      mErrorCode(OK) {
36272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mLooper != NULL);
36372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
36472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString mime;
36572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &mime));
36672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
36772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!strncasecmp("video/", mime.c_str(), 6)) {
36872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mIsVideo = true;
36972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
37072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
37172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
37272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mPuller = new Puller(source);
37372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
37472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
37572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
37672cecca17d735db6532c45f0a7e10c47ee6f065aChong ZhangMediaCodecSource::~MediaCodecSource() {
37772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    releaseEncoder();
37872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
37972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->stop();
38072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->unregisterHandler(mReflector->id());
38172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
38272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
38372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::init() {
38472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = initEncoder();
38572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
38672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
38772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        releaseEncoder();
38872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
38972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
39072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
39172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
39272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
39372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::initEncoder() {
39472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mReflector = new AHandlerReflector<MediaCodecSource>(this);
39572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mLooper->registerHandler(mReflector);
39672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
39772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper = new ALooper;
39872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->setName("codec_looper");
39972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mCodecLooper->start();
40072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
40172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_METADATA_INPUT) {
40272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputFormat->setInt32("store-metadata-in-buffers", 1);
40372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
40472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
40572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
40672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mOutputFormat->setInt32("create-input-buffers-suspended", 1);
40772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
40872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
40972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    AString outputMIME;
41072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mOutputFormat->findString("mime", &outputMIME));
41172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    Vector<AString> matchingCodecs;
41316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    MediaCodecList::findMatchingCodecs(
41416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            outputMIME.c_str(), true /* encoder */,
41516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            ((mFlags & FLAG_PREFER_SOFTWARE_CODEC) ? MediaCodecList::kPreferSoftwareCodecs : 0),
41616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            &matchingCodecs);
41772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
41816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    status_t err = NO_INIT;
41916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    for (size_t ix = 0; ix < matchingCodecs.size(); ++ix) {
42016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = MediaCodec::CreateByComponentName(
42116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                mCodecLooper, matchingCodecs[ix]);
42216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
42316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (mEncoder == NULL) {
42416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            continue;
42516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
42616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar
42716fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str());
42872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
42916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, mReflector);
43016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->setCallback(mEncoderActivityNotify);
43172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
43216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        err = mEncoder->configure(
43316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    mOutputFormat,
43416fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* nativeWindow */,
43516fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    NULL /* crypto */,
43616fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar                    MediaCodec::CONFIGURE_FLAG_ENCODE);
437421f47ca9c2dcc78584b2bb609c3755483b55155Marco Nelissen
43816fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        if (err == OK) {
43916fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar            break;
44016fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        }
44116fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder->release();
44216fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar        mEncoder = NULL;
44316fcc47c113e63efa69f5af5decf1ad46ec653a9Lajos Molnar    }
44472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
44572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
44672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
44772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
44872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
44972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->getOutputFormat(&mOutputFormat);
45072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    convertMessageToMetaData(mOutputFormat, mMeta);
45172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
45272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
45372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mIsVideo);
45472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
455e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        if (mGraphicBufferConsumer != NULL) {
456e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // When using persistent surface, we are only interested in the
457e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // consumer, but have to use PersistentSurface as a wrapper to
458e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            // pass consumer over messages (similar to BufferProducerWrapper)
4598f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            err = mEncoder->setInputSurface(
460e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang                    new PersistentSurface(NULL, mGraphicBufferConsumer));
461e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        } else {
462e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang            err = mEncoder->createInputSurface(&mGraphicBufferProducer);
463e2a2dfcbf0c9d6bb7139263ecf0d8e53b4ca1049Chong Zhang        }
46472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
46572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
46672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
46772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
46872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
46972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
470c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    sp<AMessage> inputFormat;
471c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    int32_t usingSwReadOften;
472c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    mSetEncoderFormat = false;
473c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    if (mEncoder->getInputFormat(&inputFormat) == OK
474c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            && inputFormat->findInt32("using-sw-read-often", &usingSwReadOften)
475c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            && usingSwReadOften) {
476c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        // this is a SW encoder; signal source to allocate SW readable buffers
477c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mSetEncoderFormat = true;
478c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mEncoderFormat = kDefaultSwVideoEncoderFormat;
479c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        mEncoderDataSpace = kDefaultSwVideoEncoderDataSpace;
480c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar    }
481c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
4821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan    err = mEncoder->start();
48372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
48572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
48672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
48772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
48816e79115e497386eaf010af388627f94314a55a3Chong Zhang    mEncoderReachedEOS = false;
48972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mErrorCode = OK;
49072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
49272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
49372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::releaseEncoder() {
49572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder == NULL) {
49672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return;
49772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
49872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
49972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder->release();
50072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mEncoder.clear();
50172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
50272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    while (!mInputBufferQueue.empty()) {
50372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        MediaBuffer *mbuf = *mInputBufferQueue.begin();
50472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mInputBufferQueue.erase(mInputBufferQueue.begin());
50572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mbuf != NULL) {
50672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mbuf->release();
50772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
50872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
50972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
51072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
51172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::postSynchronouslyAndReturnError(
51272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        const sp<AMessage> &msg) {
51372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    sp<AMessage> response;
51472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = msg->postAndAwaitResponse(&response);
51572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
51672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (err != OK) {
51772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return err;
51872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
51972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (!response->findInt32("err", &err)) {
52172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        err = OK;
52272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
52372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return err;
52572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
52672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
52772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::signalEOS(status_t err) {
52816e79115e497386eaf010af388627f94314a55a3Chong Zhang    if (!mEncoderReachedEOS) {
52916e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGV("encoder (%s) reached EOS", mIsVideo ? "video" : "audio");
53072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        {
53172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            Mutex::Autolock autoLock(mOutputBufferLock);
53272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // release all unread media buffers
53372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            for (List<MediaBuffer*>::iterator it = mOutputBufferQueue.begin();
53472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    it != mOutputBufferQueue.end(); it++) {
53572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                (*it)->release();
53672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
53772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOutputBufferQueue.clear();
53816e79115e497386eaf010af388627f94314a55a3Chong Zhang            mEncoderReachedEOS = true;
53972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mErrorCode = err;
54072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mOutputBufferCond.signal();
54172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
54272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
54372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        releaseEncoder();
54472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
54516e79115e497386eaf010af388627f94314a55a3Chong Zhang    if (mStopping && mEncoderReachedEOS) {
54616e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopped", mIsVideo ? "video" : "audio");
54772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // posting reply to everyone that's waiting
5483f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        List<sp<AReplyToken>>::iterator it;
54972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        for (it = mStopReplyIDQueue.begin();
55072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                it != mStopReplyIDQueue.end(); it++) {
55172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(*it);
55272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
55372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.clear();
55472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = false;
55572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
55672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
55772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
55872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::suspend() {
55972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
56072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder != NULL) {
56172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> params = new AMessage;
56272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        params->setInt32("drop-input-frames", true);
56372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mEncoder->setParameters(params);
56472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
56572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
56672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
56772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::resume(int64_t skipFramesBeforeUs) {
56872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    CHECK(mFlags & FLAG_USE_SURFACE_INPUT);
56972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mEncoder != NULL) {
57072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> params = new AMessage;
57172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        params->setInt32("drop-input-frames", false);
57272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (skipFramesBeforeUs > 0) {
57372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            params->setInt64("skip-frames-before", skipFramesBeforeUs);
57472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
57572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mEncoder->setParameters(params);
57672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
57772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
57872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
57972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::feedEncoderInputBuffers() {
58072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    while (!mInputBufferQueue.empty()
58172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            && !mAvailEncoderInputIndices.empty()) {
58272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        MediaBuffer* mbuf = *mInputBufferQueue.begin();
58372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mInputBufferQueue.erase(mInputBufferQueue.begin());
58472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
58572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t bufferIndex = *mAvailEncoderInputIndices.begin();
58672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mAvailEncoderInputIndices.erase(mAvailEncoderInputIndices.begin());
58772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
58872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        int64_t timeUs = 0ll;
58972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        uint32_t flags = 0;
59072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        size_t size = 0;
59172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
59272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mbuf != NULL) {
59372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
594d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim            timeUs += mInputBufferTimeOffsetUs;
59572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
59672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // push decoding time for video, or drift time for audio
59772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
59872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDecodingTimeQueue.push_back(timeUs);
59972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
60072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#if DEBUG_DRIFT_TIME
60172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mFirstSampleTimeUs < 0ll) {
60272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mFirstSampleTimeUs = timeUs;
60372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
60472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
60572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                int64_t driftTimeUs = 0;
60672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                if (mbuf->meta_data()->findInt64(kKeyDriftTime, &driftTimeUs)
60772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                        && driftTimeUs) {
60872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    driftTimeUs = timeUs - mFirstSampleTimeUs - driftTimeUs;
60972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                }
61072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mDriftTimeQueue.push_back(driftTimeUs);
61172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang#endif // DEBUG_DRIFT_TIME
61272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
61372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6141099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            sp<ABuffer> inbuf;
6151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getInputBuffer(bufferIndex, &inbuf);
6161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (err != OK || inbuf == NULL) {
6171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->release();
6181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
6191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
6201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
6211099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
62272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            size = mbuf->size();
62372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
6241099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            memcpy(inbuf->data(), mbuf->data(), size);
62572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
62672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mIsVideo) {
62772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // video encoder will release MediaBuffer when done
62872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                // with underlying data.
6291099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                inbuf->setMediaBufferBase(mbuf);
63072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            } else {
63172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mbuf->release();
63272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
63372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
63472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            flags = MediaCodec::BUFFER_FLAG_EOS;
63572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
63672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
63772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        status_t err = mEncoder->queueInputBuffer(
63872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                bufferIndex, 0, size, timeUs, flags);
63972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
64072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
64172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
64272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
64372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
64472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
64572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
64672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
64772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
64872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangstatus_t MediaCodecSource::onStart(MetaData *params) {
64972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStopping) {
65072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGE("Failed to start while we're stopping");
65172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return INVALID_OPERATION;
65272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
65372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
65472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mStarted) {
65572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        ALOGI("MediaCodecSource (%s) resuming", mIsVideo ? "video" : "audio");
65672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
65772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            resume();
65872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
65972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mPuller != NULL);
66072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPuller->resume();
66172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
66272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        return OK;
66372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
66472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
66572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) starting", mIsVideo ? "video" : "audio");
66672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
66772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    status_t err = OK;
66872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
66972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    if (mFlags & FLAG_USE_SURFACE_INPUT) {
67072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        int64_t startTimeUs;
67172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (!params || !params->findInt64(kKeyTime, &startTimeUs)) {
67272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            startTimeUs = -1ll;
67372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
67472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        resume(startTimeUs);
67572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    } else {
67672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(mPuller != NULL);
677c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        sp<MetaData> meta = params;
678c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        if (mSetEncoderFormat) {
679c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            if (meta == NULL) {
680c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar                meta = new MetaData;
681c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            }
682c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyPixelFormat, mEncoderFormat);
683c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar            meta->setInt32(kKeyColorSpace, mEncoderDataSpace);
684c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        }
685c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar
6861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar        sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector);
687c93a13669ce1b5a9e6527b4c86c9d8f5e92be828Lajos Molnar        err = mPuller->start(meta.get(), notify);
68872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (err != OK) {
68972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            return err;
69072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
69172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
69272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    ALOGI("MediaCodecSource (%s) started", mIsVideo ? "video" : "audio");
69472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    mStarted = true;
69672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    return OK;
69772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
69872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
69972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhangvoid MediaCodecSource::onMessageReceived(const sp<AMessage> &msg) {
70072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    switch (msg->what()) {
70172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPullerNotify:
70272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
70372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        MediaBuffer *mbuf;
70472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->findPointer("accessUnit", (void**)&mbuf));
70572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
70672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mbuf == NULL) {
70716e79115e497386eaf010af388627f94314a55a3Chong Zhang            ALOGV("puller (%s) reached EOS",
70872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mIsVideo ? "video" : "audio");
70916e79115e497386eaf010af388627f94314a55a3Chong Zhang            signalEOS();
71072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
71172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
71272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
71372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            ALOGV("got msg '%s' after encoder shutdown.",
71472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                  msg->debugString().c_str());
71572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
71672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            if (mbuf != NULL) {
71772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                mbuf->release();
71872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            }
71916e79115e497386eaf010af388627f94314a55a3Chong Zhang
72072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
72172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
72272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
72372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mInputBufferQueue.push_back(mbuf);
72472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
72572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        feedEncoderInputBuffers();
72672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
72772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
72872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
72972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatEncoderActivity:
73072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
73172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mEncoder == NULL) {
73272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
73372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
73472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7351099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        int32_t cbID;
7361099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        CHECK(msg->findInt32("callbackID", &cbID));
7371099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        if (cbID == MediaCodec::CB_INPUT_AVAILABLE) {
7381099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
7391099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
7401099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7411099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mAvailEncoderInputIndices.push_back(index);
7421099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            feedEncoderInputBuffers();
7431099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan        } else if (cbID == MediaCodec::CB_OUTPUT_AVAILABLE) {
7441099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t index;
7451099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t offset;
7461099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            size_t size;
7471099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int64_t timeUs;
7481099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            int32_t flags;
7491099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7501099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("index", &index));
7511099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("offset", &offset));
7521099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findSize("size", &size));
7531099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt64("timeUs", &timeUs));
7541099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("flags", &flags));
7551099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
7561099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_EOS) {
7571099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mEncoder->releaseOutputBuffer(index);
7581099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
7591099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
7601099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
761f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
7621099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            sp<ABuffer> outbuf;
7631099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err = mEncoder->getOutputBuffer(index, &outbuf);
7641099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (err != OK || outbuf == NULL) {
7651099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                signalEOS();
7661099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                break;
7671099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
768f2a64852a4a48c5a3d8a08ffcda20d6884586672Chong Zhang
7691099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            MediaBuffer *mbuf = new MediaBuffer(outbuf->size());
7701099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            memcpy(mbuf->data(), outbuf->data(), outbuf->size());
77172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7721099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (!(flags & MediaCodec::BUFFER_FLAG_CODECCONFIG)) {
7731099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                if (mIsVideo) {
7741099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t decodingTimeUs;
7751099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    if (mFlags & FLAG_USE_SURFACE_INPUT) {
776d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        // Time offset is not applied at
777d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        // feedEncoderInputBuffer() in surface input case.
778d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim                        timeUs += mInputBufferTimeOffsetUs;
7791099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // GraphicBufferSource is supposed to discard samples
7801099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // queued before start, and offset timeUs by start time
7811099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        CHECK_GE(timeUs, 0ll);
7821099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // TODO:
7831099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // Decoding time for surface source is unavailable,
7841099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // use presentation time for now. May need to move
7851099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        // this logic into MediaCodec.
7861099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = timeUs;
7871099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    } else {
7881099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        CHECK(!mDecodingTimeQueue.empty());
7891099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        decodingTimeUs = *(mDecodingTimeQueue.begin());
7901099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                        mDecodingTimeQueue.erase(mDecodingTimeQueue.begin());
7911099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    }
7921099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs);
79372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
7941099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[video] time %" PRId64 " us (%.2f secs), dts/pts diff %" PRId64,
7951099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, decodingTimeUs - timeUs);
7961099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                } else {
7971099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    int64_t driftTimeUs = 0;
7981099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#if DEBUG_DRIFT_TIME
7991099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    CHECK(!mDriftTimeQueue.empty());
8001099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    driftTimeUs = *(mDriftTimeQueue.begin());
8011099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mDriftTimeQueue.erase(mDriftTimeQueue.begin());
8021099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mbuf->meta_data()->setInt64(kKeyDriftTime, driftTimeUs);
8031099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan#endif // DEBUG_DRIFT_TIME
8041099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    ALOGV("[audio] time %" PRId64 " us (%.2f secs), drift %" PRId64,
8051099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                            timeUs, timeUs / 1E6, driftTimeUs);
8061099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                }
8071099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt64(kKeyTime, timeUs);
8081099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            } else {
8091099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsCodecConfig, true);
8101099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8111099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            if (flags & MediaCodec::BUFFER_FLAG_SYNCFRAME) {
8121099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mbuf->meta_data()->setInt32(kKeyIsSyncFrame, true);
8131099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8141099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mbuf->setObserver(this);
8151099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mbuf->add_ref();
8161099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8171099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            {
8181099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                Mutex::Autolock autoLock(mOutputBufferLock);
8191099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mOutputBufferQueue.push_back(mbuf);
8201099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                mOutputBufferCond.signal();
8211099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            }
8221099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan
8231099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            mEncoder->releaseOutputBuffer(index);
8241099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       } else if (cbID == MediaCodec::CB_ERROR) {
8251099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            status_t err;
8261099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            CHECK(msg->findInt32("err", &err));
8271099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            ALOGE("Encoder (%s) reported error : 0x%x",
8281099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan                    mIsVideo ? "video" : "audio", err);
8291099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan            signalEOS();
8301099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       }
8311099188151eb63af24ecf542b58d4257bbb8236aPraveen Chavan       break;
83272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
83372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStart:
83472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
8353f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
83672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
83772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
83872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<RefBase> obj;
83972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->findObject("meta", &obj));
84072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        MetaData *params = static_cast<MetaData *>(obj.get());
84172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
84272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        sp<AMessage> response = new AMessage;
84372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->setInt32("err", onStart(params));
84472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        response->postReply(replyID);
84572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
84672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
84772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatStop:
84872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
84916e79115e497386eaf010af388627f94314a55a3Chong Zhang        ALOGI("encoder (%s) stopping", mIsVideo ? "video" : "audio");
85072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
8513f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        sp<AReplyToken> replyID;
85272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        CHECK(msg->senderAwaitsResponse(&replyID));
85372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
85416e79115e497386eaf010af388627f94314a55a3Chong Zhang        if (mEncoderReachedEOS) {
85572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // if we already reached EOS, reply and return now
85616e79115e497386eaf010af388627f94314a55a3Chong Zhang            ALOGI("encoder (%s) already stopped",
85772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang                    mIsVideo ? "video" : "audio");
85872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            (new AMessage)->postReply(replyID);
85972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
86072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
86172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
86272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopReplyIDQueue.push_back(replyID);
86372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mStopping) {
86472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // nothing to do if we're already stopping, reply will be posted
86572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            // to all when we're stopped.
86672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            break;
86772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
86872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
86972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        mStopping = true;
87072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
87172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // if using surface, signal source EOS and wait for EOS to come back.
87272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        // otherwise, release encoder and post EOS if haven't done already
87372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        if (mFlags & FLAG_USE_SURFACE_INPUT) {
87472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mEncoder->signalEndOfInputStream();
87572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
87672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            signalEOS();
87772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
87872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
87972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
88072cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    case kWhatPause:
88172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    {
882d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        if (mFlags & FLAG_USE_SURFACE_INPUT) {
88372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            suspend();
88472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        } else {
88572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            CHECK(mPuller != NULL);
88672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang            mPuller->pause();
88772cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        }
88872cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        break;
88972cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
890d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    case kWhatSetInputBufferTimeOffset:
891d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    {
892d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AReplyToken> replyID;
893d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->senderAwaitsResponse(&replyID));
894d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
895d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        CHECK(msg->findInt64("time-offset-us", &mInputBufferTimeOffsetUs));
896d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim
897d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        sp<AMessage> response = new AMessage;
898d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        response->postReply(replyID);
899d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim        break;
900d008275796ac4cccf85fefce53cef733a49bc1faWonsik Kim    }
90172cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    default:
90272cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang        TRESPASS();
90372cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang    }
90472cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang}
90572cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang
90672cecca17d735db6532c45f0a7e10c47ee6f065aChong Zhang} // namespace android
907