100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar/*
200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * Copyright 2016, The Android Open Source Project
300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *
400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * Licensed under the Apache License, Version 2.0 (the "License");
500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * you may not use this file except in compliance with the License.
600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * You may obtain a copy of the License at
700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *
800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *     http://www.apache.org/licenses/LICENSE-2.0
900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar *
1000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * Unless required by applicable law or agreed to in writing, software
1100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * distributed under the License is distributed on an "AS IS" BASIS,
1200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * See the License for the specific language governing permissions and
1400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar * limitations under the License.
1500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar */
1600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
174f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim//#define LOG_NDEBUG 0
184f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim#define LOG_TAG "SimpleDecodingSource"
194f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim#include <utils/Log.h>
204f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim
2100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <gui/Surface.h>
2200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
2300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/ICrypto.h>
247e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h>
254278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen#include <media/stagefright/MediaDefs.h>
2600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/ALooper.h>
2700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/AMessage.h>
2800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
2900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaBuffer.h>
3000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaCodecList.h>
3100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaCodec.h>
3200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MetaData.h>
3300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/SimpleDecodingSource.h>
3400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/Utils.h>
3500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
3600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarusing namespace android;
3700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
3800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarconst int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds
393ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnarconst int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds
4000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
4100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar//static
4200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarsp<SimpleDecodingSource> SimpleDecodingSource::Create(
43ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang        const sp<MediaSource> &source, uint32_t flags) {
44defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopian    return SimpleDecodingSource::Create(source, flags, nullptr, nullptr);
45defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopian}
46defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopian
47defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopian//static
48defb1b0b7e082621a10763d1bd7a4a01e280fdf0Mathias Agopiansp<SimpleDecodingSource> SimpleDecodingSource::Create(
49ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang        const sp<MediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow,
504f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        const char *desiredCodec, bool skipMediaCodecList) {
5100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<Surface> surface = static_cast<Surface*>(nativeWindow.get());
5200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    const char *mime = NULL;
5300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<MetaData> meta = source->getFormat();
5400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    CHECK(meta->findCString(kKeyMIMEType, &mime));
5500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
5600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<AMessage> format = new AMessage;
575bd99f9211c533058be9f41bc966be1f2f501f13Lajos Molnar    if (convertMetaDataToMessage(source->getFormat(), &format) != OK) {
585bd99f9211c533058be9f41bc966be1f2f501f13Lajos Molnar        return NULL;
595bd99f9211c533058be9f41bc966be1f2f501f13Lajos Molnar    }
6000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
6100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Vector<AString> matchingCodecs;
6200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    MediaCodecList::findMatchingCodecs(
6300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            mime, false /* encoder */, flags, &matchingCodecs);
6400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
6500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<ALooper> looper = new ALooper;
6600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    looper->setName("stagefright");
6700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    looper->start();
6800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
6900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<MediaCodec> codec;
704f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim    auto configure = [=](const sp<MediaCodec> &codec, const AString &componentName)
714f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim            -> sp<SimpleDecodingSource> {
7200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (codec != NULL) {
7300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGI("Successfully allocated codec '%s'", componentName.c_str());
7400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
7500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            status_t err = codec->configure(format, surface, NULL /* crypto */, 0 /* flags */);
764f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim            sp<AMessage> outFormat;
7700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (err == OK) {
784f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim                err = codec->getOutputFormat(&outFormat);
7900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
8000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (err == OK) {
814278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                return new SimpleDecodingSource(codec, source, looper,
824278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                        surface != NULL,
834278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                        strcmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS) == 0,
844f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim                        outFormat);
8500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
8600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
8700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGD("Failed to configure codec '%s'", componentName.c_str());
8800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            codec->release();
894f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        }
904f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        return NULL;
914f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim    };
924f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim
934f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim    if (skipMediaCodecList) {
944f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        codec = MediaCodec::CreateByComponentName(looper, desiredCodec);
954f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        return configure(codec, desiredCodec);
964f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim    }
974f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim
984f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
994f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        const AString &componentName = matchingCodecs[i];
1004f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        if (desiredCodec != NULL && componentName.compare(desiredCodec)) {
1014f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim            continue;
1024f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        }
1034f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim
1044f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        ALOGV("Attempting to allocate codec '%s'", componentName.c_str());
1054f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim
1064f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        codec = MediaCodec::CreateByComponentName(looper, componentName);
1074f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        sp<SimpleDecodingSource> res = configure(codec, componentName);
1084f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        if (res != NULL) {
1094f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim            return res;
1104f87426e12f5f12e0724519e77f8237a6b2d5dacWonsik Kim        } else {
11100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            codec = NULL;
11200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
11300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
11400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
11500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    looper->stop();
11600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    ALOGE("No matching decoder! (mime: %s)", mime);
11700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return NULL;
11800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
11900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
12000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::SimpleDecodingSource(
121ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang        const sp<MediaCodec> &codec, const sp<MediaSource> &source, const sp<ALooper> &looper,
1224278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen        bool usingSurface, bool isVorbis, const sp<AMessage> &format)
12300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    : mCodec(codec),
12400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mSource(source),
12500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mLooper(looper),
12600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mUsingSurface(usingSurface),
1274278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen      mIsVorbis(isVorbis),
12800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mProtectedState(format) {
12900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    mCodec->getName(&mComponentName);
13000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
13100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
13200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::~SimpleDecodingSource() {
13300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    mCodec->release();
13400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    mLooper->stop();
13500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
13600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
13700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::start(MetaData *params) {
13800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    (void)params;
13900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Mutexed<ProtectedState>::Locked me(mProtectedState);
14000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState != INIT) {
14100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return -EINVAL;
14200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
14300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res = mCodec->start();
14400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (res == OK) {
14500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        res = mSource->start();
14600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
14700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
14800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (res == OK) {
14900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mState = STARTED;
15000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mQueuedInputEOS = false;
15100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mGotOutputEOS = false;
15200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    } else {
15300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mState = ERROR;
15400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
15500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
15600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return res;
15700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
15800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
15900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::stop() {
16000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Mutexed<ProtectedState>::Locked me(mProtectedState);
16100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState != STARTED) {
16200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return -EINVAL;
16300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
16400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
16500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    // wait for any pending reads to complete
16600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    me->mState = STOPPING;
16700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    while (me->mReading) {
16800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me.waitForCondition(me->mReadCondition);
16900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
17000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
17100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res1 = mCodec->stop();
17200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (res1 != OK) {
17300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        mCodec->release();
17400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
17500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res2 = mSource->stop();
17600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (res1 == OK && res2 == OK) {
17700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mState = STOPPED;
17800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    } else {
17900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mState = ERROR;
18000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
18100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return res1 != OK ? res1 : res2;
18200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
18300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
18400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarsp<MetaData> SimpleDecodingSource::getFormat() {
18500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Mutexed<ProtectedState>::Locked me(mProtectedState);
18600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState == STARTED || me->mState == INIT) {
18700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        sp<MetaData> meta = new MetaData();
18800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        convertMessageToMetaData(me->mFormat, meta);
18900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return meta;
19000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
19100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return NULL;
19200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
19300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
19400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::ProtectedState::ProtectedState(const sp<AMessage> &format)
19500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    : mReading(false),
19600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mFormat(format),
19700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mState(INIT),
19800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mQueuedInputEOS(false),
19900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mGotOutputEOS(false) {
20000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
20100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
20200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::read(
2031889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang        MediaBufferBase **buffer, const ReadOptions *options) {
20400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    *buffer = NULL;
20500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
20600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Mutexed<ProtectedState>::Locked me(mProtectedState);
20700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState != STARTED) {
20800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return ERROR_END_OF_STREAM;
20900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
21000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    me->mReading = true;
21100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
21200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res = doRead(me, buffer, options);
21300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
21400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    me.lock();
21500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    me->mReading = false;
21600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState != STARTED) {
21700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mReadCondition.signal();
21800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
21900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
22000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return res;
22100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
22200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
22300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::doRead(
2241889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang        Mutexed<ProtectedState>::Locked &me, MediaBufferBase **buffer, const ReadOptions *options) {
22500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    // |me| is always locked on entry, but is allowed to be unlocked on exit
22600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    CHECK_EQ(me->mState, STARTED);
22700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
22800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    size_t out_ix, in_ix, out_offset, out_size;
22900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    int64_t out_pts;
23000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    uint32_t out_flags;
23100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res;
23200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
23300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    // flush codec on seek
234ba8128f9db82da66f28c6e6740d4721d80da954eDongwon Kang    MediaSource::ReadOptions::SeekMode mode;
23500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (options != NULL && options->getSeekTo(&out_pts, &mode)) {
23600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mQueuedInputEOS = false;
23700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mGotOutputEOS = false;
23800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        mCodec->flush();
23900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
24000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
24100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mGotOutputEOS) {
24200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return ERROR_END_OF_STREAM;
24300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
24400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
2453ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar    for (int retries = 0; ++retries; ) {
24600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // If we fill all available input buffers, we should expect that
24700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // the codec produces at least one output buffer. Also, the codec
24800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // should produce an output buffer in at most 1 seconds. Retry a
24900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // few times nonetheless.
25000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        while (!me->mQueuedInputEOS) {
2513ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar            // allow some time to get input buffer after flush
2523ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar            res = mCodec->dequeueInputBuffer(&in_ix, kTimeoutWaitForInputUs);
25300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (res == -EAGAIN) {
25400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                // no available input buffers
25500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                break;
25600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
25700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
2587e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            sp<MediaCodecBuffer> in_buffer;
25900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (res == OK) {
26000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                res = mCodec->getInputBuffer(in_ix, &in_buffer);
26100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
26200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
26300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (res != OK || in_buffer == NULL) {
26400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                ALOGW("[%s] could not get input buffer #%zu",
26500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        mComponentName.c_str(), in_ix);
26600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                me->mState = ERROR;
26700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                return UNKNOWN_ERROR;
26800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
26900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
2701889c3edad32995c0cf26ae2248fe7c957b7ec84Dongwon Kang            MediaBufferBase *in_buf;
27100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            while (true) {
27200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                in_buf = NULL;
27300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                me.unlock();
27400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                res = mSource->read(&in_buf, options);
27500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                me.lock();
27600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                if (res != OK || me->mState != STARTED) {
27700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    if (in_buf != NULL) {
27800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        in_buf->release();
27900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        in_buf = NULL;
28000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    }
28100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
28200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    // queue EOS
28300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    me->mQueuedInputEOS = true;
28400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    if (mCodec->queueInputBuffer(
28500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                                 in_ix, 0 /* offset */, 0 /* size */,
28600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                                 0 /* pts */, MediaCodec::BUFFER_FLAG_EOS) != OK) {
28700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        ALOGI("[%s] failed to queue input EOS", mComponentName.c_str());
28800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        me->mState = ERROR;
28900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        return UNKNOWN_ERROR;
29000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    }
29100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
29200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    // don't stop on EOS, but report error or EOS on stop
29300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    if (res != ERROR_END_OF_STREAM) {
29400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        me->mState = ERROR;
29500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        return res;
29600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    }
29700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    if (me->mState != STARTED) {
29800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        return ERROR_END_OF_STREAM;
29900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    }
30000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    break;
30100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                }
30200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                if (in_buf == NULL) { // should not happen
30300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    continue;
30400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                } else if (in_buf->range_length() != 0) {
30500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    break;
30600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                }
30700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                in_buf->release();
30800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
30900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
31000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (in_buf != NULL) {
31100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                int64_t timestampUs = 0;
3123d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                CHECK(in_buf->meta_data().findInt64(kKeyTime, &timestampUs));
3134278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                if (in_buf->range_length() + (mIsVorbis ? 4 : 0) > in_buffer->capacity()) {
31400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    ALOGW("'%s' received %zu input bytes for buffer of size %zu",
31500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                            mComponentName.c_str(),
3164278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                            in_buf->range_length() + (mIsVorbis ? 4 : 0), in_buffer->capacity());
31700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                }
3184278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                size_t cpLen = min(in_buf->range_length(), in_buffer->capacity());
31900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                memcpy(in_buffer->base(), (uint8_t *)in_buf->data() + in_buf->range_offset(),
3204278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                        cpLen );
3214278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen
3224278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                if (mIsVorbis) {
3234278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                    int32_t numPageSamples;
3243d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen                    if (!in_buf->meta_data().findInt32(kKeyValidSamples, &numPageSamples)) {
3254278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                        numPageSamples = -1;
3264278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                    }
3274278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                    memcpy(in_buffer->base() + cpLen, &numPageSamples, sizeof(numPageSamples));
3284278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                }
32900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
33000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                res = mCodec->queueInputBuffer(
3314278ba02628d915b52d59dcf5477880cf99f39cdMarco Nelissen                        in_ix, 0 /* offset */, in_buf->range_length() + (mIsVorbis ? 4 : 0),
33200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        timestampUs, 0 /* flags */);
33300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                if (res != OK) {
33400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    ALOGI("[%s] failed to queue input buffer #%zu", mComponentName.c_str(), in_ix);
33500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    me->mState = ERROR;
33600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                }
33700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                in_buf->release();
33800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
33900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
34000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
34100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me.unlock();
34200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        res = mCodec->dequeueOutputBuffer(
34300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                &out_ix, &out_offset, &out_size, &out_pts,
34400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                &out_flags, kTimeoutWaitForOutputUs /* timeoutUs */);
34500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me.lock();
34600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // abort read on stop
34700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (me->mState != STARTED) {
34800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (res == OK) {
34900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                mCodec->releaseOutputBuffer(out_ix);
35000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
35100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            return ERROR_END_OF_STREAM;
35200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
35300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
35400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (res == -EAGAIN) {
35500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGD("[%s] did not produce an output buffer. retry count: %d",
35600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                  mComponentName.c_str(), retries);
35700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            continue;
35800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        } else if (res == INFO_FORMAT_CHANGED) {
35900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (mCodec->getOutputFormat(&me->mFormat) != OK) {
36000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                me->mState = ERROR;
36100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                res = UNKNOWN_ERROR;
36200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
36300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            return res;
36400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        } else if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
36500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGV("output buffers changed");
36600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            continue;
36700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        } else if (res != OK) {
36800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            me->mState = ERROR;
36900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            return res;
37000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
37100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
3727e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        sp<MediaCodecBuffer> out_buffer;
37300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        res = mCodec->getOutputBuffer(out_ix, &out_buffer);
37400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (res != OK) {
37500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGW("[%s] could not get output buffer #%zu",
37600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    mComponentName.c_str(), out_ix);
37700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            me->mState = ERROR;
37800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            return UNKNOWN_ERROR;
37900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
38000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (out_flags & MediaCodec::BUFFER_FLAG_EOS) {
38100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            me->mGotOutputEOS = true;
38200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            // return EOS immediately if last buffer is empty
38300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (out_size == 0) {
38400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                mCodec->releaseOutputBuffer(out_ix);
38500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                return ERROR_END_OF_STREAM;
38600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
38700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
38800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
38900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (mUsingSurface && out_size > 0) {
39000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            *buffer = new MediaBuffer(0);
39100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            mCodec->renderOutputBufferAndRelease(out_ix);
39200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        } else {
39300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            *buffer = new MediaBuffer(out_size);
39400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            CHECK_LE(out_buffer->size(), (*buffer)->size());
39500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            memcpy((*buffer)->data(), out_buffer->data(), out_buffer->size());
3963d21ae3fad5a894cf15f2e7e7a1d54d0f3d19db0Marco Nelissen            (*buffer)->meta_data().setInt64(kKeyTime, out_pts);
39700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            mCodec->releaseOutputBuffer(out_ix);
39800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
39900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return OK;
40000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
40100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
40200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return TIMED_OUT;
40300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
404