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
1700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <gui/Surface.h>
1800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
1900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/ICrypto.h>
2000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/ABuffer.h>
2100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/ALooper.h>
2200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/AMessage.h>
2300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/foundation/AUtils.h>
2400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaBuffer.h>
2500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaCodecList.h>
2600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MediaCodec.h>
2700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/MetaData.h>
2800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/SimpleDecodingSource.h>
2900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar#include <media/stagefright/Utils.h>
3000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
3100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarusing namespace android;
3200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
3300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarconst int64_t kTimeoutWaitForOutputUs = 500000; // 0.5 seconds
343ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnarconst int64_t kTimeoutWaitForInputUs = 5000; // 5 milliseconds
3500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
3600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar//static
3700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarsp<SimpleDecodingSource> SimpleDecodingSource::Create(
38963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar        const sp<IMediaSource> &source, uint32_t flags, const sp<ANativeWindow> &nativeWindow,
39963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar        const char *desiredCodec) {
4000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<Surface> surface = static_cast<Surface*>(nativeWindow.get());
4100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    const char *mime = NULL;
4200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<MetaData> meta = source->getFormat();
4300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    CHECK(meta->findCString(kKeyMIMEType, &mime));
4400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
4500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<AMessage> format = new AMessage;
4600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    convertMetaDataToMessage(source->getFormat(), &format);
4700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
4800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Vector<AString> matchingCodecs;
4900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    MediaCodecList::findMatchingCodecs(
5000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            mime, false /* encoder */, flags, &matchingCodecs);
5100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
5200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<ALooper> looper = new ALooper;
5300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    looper->setName("stagefright");
5400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    looper->start();
5500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
5600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    sp<MediaCodec> codec;
5700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
5800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    for (size_t i = 0; i < matchingCodecs.size(); ++i) {
5900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        const AString &componentName = matchingCodecs[i];
60963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar        if (desiredCodec != NULL && componentName.compare(desiredCodec)) {
61963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar            continue;
62963f181c57a26dd23bd9dff263614bbb38960888Lajos Molnar        }
6300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
6400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        ALOGV("Attempting to allocate codec '%s'", componentName.c_str());
6500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
6600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        codec = MediaCodec::CreateByComponentName(looper, componentName);
6700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (codec != NULL) {
6800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGI("Successfully allocated codec '%s'", componentName.c_str());
6900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
7000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            status_t err = codec->configure(format, surface, NULL /* crypto */, 0 /* flags */);
7100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (err == OK) {
7200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                err = codec->getOutputFormat(&format);
7300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
7400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (err == OK) {
7500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                return new SimpleDecodingSource(codec, source, looper, surface != NULL, format);
7600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
7700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
7800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGD("Failed to configure codec '%s'", componentName.c_str());
7900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            codec->release();
8000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            codec = NULL;
8100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
8200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
8300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
8400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    looper->stop();
8500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    ALOGE("No matching decoder! (mime: %s)", mime);
8600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return NULL;
8700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
8800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
8900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::SimpleDecodingSource(
9000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        const sp<MediaCodec> &codec, const sp<IMediaSource> &source, const sp<ALooper> &looper,
9100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        bool usingSurface, const sp<AMessage> &format)
9200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    : mCodec(codec),
9300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mSource(source),
9400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mLooper(looper),
9500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mUsingSurface(usingSurface),
9600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mProtectedState(format) {
9700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    mCodec->getName(&mComponentName);
9800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
9900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
10000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::~SimpleDecodingSource() {
10100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    mCodec->release();
10200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    mLooper->stop();
10300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
10400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
10500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::start(MetaData *params) {
10600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    (void)params;
10700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Mutexed<ProtectedState>::Locked me(mProtectedState);
10800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState != INIT) {
10900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return -EINVAL;
11000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
11100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res = mCodec->start();
11200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (res == OK) {
11300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        res = mSource->start();
11400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
11500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
11600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (res == OK) {
11700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mState = STARTED;
11800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mQueuedInputEOS = false;
11900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mGotOutputEOS = false;
12000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    } else {
12100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mState = ERROR;
12200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
12300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
12400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return res;
12500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
12600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
12700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::stop() {
12800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Mutexed<ProtectedState>::Locked me(mProtectedState);
12900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState != STARTED) {
13000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return -EINVAL;
13100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
13200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
13300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    // wait for any pending reads to complete
13400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    me->mState = STOPPING;
13500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    while (me->mReading) {
13600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me.waitForCondition(me->mReadCondition);
13700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
13800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
13900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res1 = mCodec->stop();
14000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (res1 != OK) {
14100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        mCodec->release();
14200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
14300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res2 = mSource->stop();
14400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (res1 == OK && res2 == OK) {
14500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mState = STOPPED;
14600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    } else {
14700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mState = ERROR;
14800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
14900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return res1 != OK ? res1 : res2;
15000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
15100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
15200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarsp<MetaData> SimpleDecodingSource::getFormat() {
15300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Mutexed<ProtectedState>::Locked me(mProtectedState);
15400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState == STARTED || me->mState == INIT) {
15500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        sp<MetaData> meta = new MetaData();
15600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        convertMessageToMetaData(me->mFormat, meta);
15700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return meta;
15800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
15900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return NULL;
16000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
16100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
16200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos MolnarSimpleDecodingSource::ProtectedState::ProtectedState(const sp<AMessage> &format)
16300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    : mReading(false),
16400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mFormat(format),
16500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mState(INIT),
16600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mQueuedInputEOS(false),
16700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar      mGotOutputEOS(false) {
16800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
16900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
17000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::read(
17100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        MediaBuffer **buffer, const ReadOptions *options) {
17200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    *buffer = NULL;
17300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
17400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    Mutexed<ProtectedState>::Locked me(mProtectedState);
17500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState != STARTED) {
17600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return ERROR_END_OF_STREAM;
17700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
17800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    me->mReading = true;
17900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
18000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res = doRead(me, buffer, options);
18100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
18200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    me.lock();
18300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    me->mReading = false;
18400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mState != STARTED) {
18500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mReadCondition.signal();
18600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
18700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
18800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return res;
18900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
19000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
19100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnarstatus_t SimpleDecodingSource::doRead(
19200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        Mutexed<ProtectedState>::Locked &me, MediaBuffer **buffer, const ReadOptions *options) {
19300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    // |me| is always locked on entry, but is allowed to be unlocked on exit
19400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    CHECK_EQ(me->mState, STARTED);
19500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
19600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    size_t out_ix, in_ix, out_offset, out_size;
19700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    int64_t out_pts;
19800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    uint32_t out_flags;
19900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    status_t res;
20000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
20100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    // flush codec on seek
20200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    IMediaSource::ReadOptions::SeekMode mode;
20300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (options != NULL && options->getSeekTo(&out_pts, &mode)) {
20400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mQueuedInputEOS = false;
20500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me->mGotOutputEOS = false;
20600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        mCodec->flush();
20700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
20800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
20900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    if (me->mGotOutputEOS) {
21000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return ERROR_END_OF_STREAM;
21100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
21200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
2133ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar    for (int retries = 0; ++retries; ) {
21400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // If we fill all available input buffers, we should expect that
21500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // the codec produces at least one output buffer. Also, the codec
21600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // should produce an output buffer in at most 1 seconds. Retry a
21700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // few times nonetheless.
21800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        while (!me->mQueuedInputEOS) {
2193ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar            // allow some time to get input buffer after flush
2203ca8f9cc3024b3306bd3782fc7d234570051a534Lajos Molnar            res = mCodec->dequeueInputBuffer(&in_ix, kTimeoutWaitForInputUs);
22100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (res == -EAGAIN) {
22200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                // no available input buffers
22300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                break;
22400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
22500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
22600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            sp<ABuffer> in_buffer;
22700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (res == OK) {
22800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                res = mCodec->getInputBuffer(in_ix, &in_buffer);
22900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
23000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
23100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (res != OK || in_buffer == NULL) {
23200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                ALOGW("[%s] could not get input buffer #%zu",
23300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        mComponentName.c_str(), in_ix);
23400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                me->mState = ERROR;
23500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                return UNKNOWN_ERROR;
23600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
23700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
23800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            MediaBuffer *in_buf;
23900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            while (true) {
24000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                in_buf = NULL;
24100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                me.unlock();
24200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                res = mSource->read(&in_buf, options);
24300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                me.lock();
24400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                if (res != OK || me->mState != STARTED) {
24500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    if (in_buf != NULL) {
24600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        in_buf->release();
24700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        in_buf = NULL;
24800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    }
24900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
25000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    // queue EOS
25100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    me->mQueuedInputEOS = true;
25200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    if (mCodec->queueInputBuffer(
25300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                                 in_ix, 0 /* offset */, 0 /* size */,
25400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                                 0 /* pts */, MediaCodec::BUFFER_FLAG_EOS) != OK) {
25500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        ALOGI("[%s] failed to queue input EOS", mComponentName.c_str());
25600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        me->mState = ERROR;
25700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        return UNKNOWN_ERROR;
25800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    }
25900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
26000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    // don't stop on EOS, but report error or EOS on stop
26100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    if (res != ERROR_END_OF_STREAM) {
26200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        me->mState = ERROR;
26300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        return res;
26400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    }
26500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    if (me->mState != STARTED) {
26600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        return ERROR_END_OF_STREAM;
26700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    }
26800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    break;
26900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                }
27000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                if (in_buf == NULL) { // should not happen
27100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    continue;
27200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                } else if (in_buf->range_length() != 0) {
27300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    break;
27400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                }
27500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                in_buf->release();
27600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
27700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
27800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (in_buf != NULL) {
27900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                int64_t timestampUs = 0;
28000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                CHECK(in_buf->meta_data()->findInt64(kKeyTime, &timestampUs));
28100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                if (in_buf->range_length() > in_buffer->capacity()) {
28200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    ALOGW("'%s' received %zu input bytes for buffer of size %zu",
28300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                            mComponentName.c_str(),
28400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                            in_buf->range_length(), in_buffer->capacity());
28500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                }
28600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                memcpy(in_buffer->base(), (uint8_t *)in_buf->data() + in_buf->range_offset(),
28700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                       min(in_buf->range_length(), in_buffer->capacity()));
28800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
28900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                res = mCodec->queueInputBuffer(
29000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        in_ix, 0 /* offset */, in_buf->range_length(),
29100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                        timestampUs, 0 /* flags */);
29200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                if (res != OK) {
29300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    ALOGI("[%s] failed to queue input buffer #%zu", mComponentName.c_str(), in_ix);
29400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    me->mState = ERROR;
29500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                }
29600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                in_buf->release();
29700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
29800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
29900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
30000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me.unlock();
30100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        res = mCodec->dequeueOutputBuffer(
30200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                &out_ix, &out_offset, &out_size, &out_pts,
30300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                &out_flags, kTimeoutWaitForOutputUs /* timeoutUs */);
30400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        me.lock();
30500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        // abort read on stop
30600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (me->mState != STARTED) {
30700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (res == OK) {
30800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                mCodec->releaseOutputBuffer(out_ix);
30900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
31000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            return ERROR_END_OF_STREAM;
31100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
31200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
31300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (res == -EAGAIN) {
31400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGD("[%s] did not produce an output buffer. retry count: %d",
31500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                  mComponentName.c_str(), retries);
31600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            continue;
31700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        } else if (res == INFO_FORMAT_CHANGED) {
31800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (mCodec->getOutputFormat(&me->mFormat) != OK) {
31900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                me->mState = ERROR;
32000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                res = UNKNOWN_ERROR;
32100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
32200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            return res;
32300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        } else if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
32400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGV("output buffers changed");
32500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            continue;
32600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        } else if (res != OK) {
32700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            me->mState = ERROR;
32800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            return res;
32900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
33000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
33100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        sp<ABuffer> out_buffer;
33200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        res = mCodec->getOutputBuffer(out_ix, &out_buffer);
33300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (res != OK) {
33400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            ALOGW("[%s] could not get output buffer #%zu",
33500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                    mComponentName.c_str(), out_ix);
33600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            me->mState = ERROR;
33700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            return UNKNOWN_ERROR;
33800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
33900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (out_flags & MediaCodec::BUFFER_FLAG_EOS) {
34000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            me->mGotOutputEOS = true;
34100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            // return EOS immediately if last buffer is empty
34200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            if (out_size == 0) {
34300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                mCodec->releaseOutputBuffer(out_ix);
34400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar                return ERROR_END_OF_STREAM;
34500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            }
34600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
34700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
34800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        if (mUsingSurface && out_size > 0) {
34900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            *buffer = new MediaBuffer(0);
35000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            mCodec->renderOutputBufferAndRelease(out_ix);
35100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        } else {
35200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            *buffer = new MediaBuffer(out_size);
35300eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            CHECK_LE(out_buffer->size(), (*buffer)->size());
35400eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            memcpy((*buffer)->data(), out_buffer->data(), out_buffer->size());
35500eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            (*buffer)->meta_data()->setInt64(kKeyTime, out_pts);
35600eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar            mCodec->releaseOutputBuffer(out_ix);
35700eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        }
35800eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar        return OK;
35900eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    }
36000eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar
36100eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar    return TIMED_OUT;
36200eb2fdb2b8f108e74c32e03b2a0e5bab3f107b6Lajos Molnar}
363