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