MediaCodec.cpp revision 7fa015217e618265ff5a844cf6961ecc316c81a4
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/*
25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright 2012, The Android Open Source Project
35778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License.
65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at
75778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
85778822d86b0337407514b9372562b86edfa91cdAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
95778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software
115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and
145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License.
155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */
165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0
185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "MediaCodec"
195778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <utils/Log.h>
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
215778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaCodec.h>
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/SoftwareRenderer.h"
245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
251a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
26ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
275778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
285778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
305b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
31ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
346f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
35e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
365778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h>
395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
40e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include "include/avc_utils.h"
41e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
425778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
455778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ALooper> &looper, const char *mime, bool encoder) {
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (codec->init(mime, true /* nameIsType */, encoder) != OK) {
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return NULL;
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return codec;
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
565778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ALooper> &looper, const char *name) {
585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) {
605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return NULL;
615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return codec;
645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
665778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
685778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
695778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mCodec(new ACodec),
707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
715778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
725778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
735778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
745778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
755778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
766507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
776507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mHaveInputSurface(false) {
785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
805778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
845778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
1025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
1035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
1045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
1055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool needDedicatedLooper = false;
1065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType && !strncasecmp(name, "video/", 6)) {
1075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        needDedicatedLooper = true;
1086f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
1096f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
1106f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
1116f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
1126f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
1136f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        const MediaCodecList *mcl = MediaCodecList::getInstance();
1146f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
1156f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
1166f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            Vector<AString> types;
1176f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            if (mcl->getSupportedTypes(codecIdx, &types) == OK) {
1186f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                for (int i = 0; i < types.size(); i++) {
1196f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                    if (types[i].startsWith("video/")) {
1206f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                        needDedicatedLooper = true;
1216f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                        break;
1226f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                    }
1236f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
1246f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
1256f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
1265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (needDedicatedLooper) {
1295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
1305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
1315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
1325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
1385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
1435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatInit, id());
1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
1475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
1495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
1505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1565778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
1575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
1581a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &nativeWindow,
1591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
1605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
1615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
1625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nativeWindow != NULL) {
1671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setObject(
1681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                "native-window",
1691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new NativeWindowWrapper(nativeWindow));
1701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
1711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
1731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
1817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
1827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
1837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
1857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
1867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
1877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
1887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
1897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
1907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
1917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
1927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
1937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
1947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
1957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
1967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
1977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
1987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
1997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
2015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatStart, id());
2025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2075778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
2085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatStop, id());
2095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
214c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
215c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatRelease, id());
216c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
217c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
218c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
219c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
220c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
2225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
2245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
2265b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
2275b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
2285b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
2295b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
2305b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
2315b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
2385b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
2454b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
2464b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
2474b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
2484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
2494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
2504b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
2514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
2524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
2535b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
2545b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
2555b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
2565b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
2575b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
2585b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
2604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
2614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
2624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
2634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
2644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
2654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
2664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
2674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
2684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
2695b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
2704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
2714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
2725b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
2735b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2745b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
2754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
2764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
2775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
3357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
3367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
3387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
3397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
3407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
355717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
356717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> msg = new AMessage(kWhatGetName, id());
357717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
358717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
359717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
360717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
361717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
362717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
363717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
364717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
365717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
366717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
367717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
368717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatFlush, id());
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
394496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
395496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
396496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
397496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
398496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
399496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
400575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
401575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
402575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
403575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
404575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
405575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4085778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(mDequeueInputReplyID);
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(mDequeueOutputReplyID);
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(replyID);
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5115778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatError:
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxError, internalError;
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("omx-error", &omxError));
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("err", &internalError));
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGE("Codec reported an error. "
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          "(omx error 0x%08x, internalError %d)",
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          omxError, internalError);
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
529aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    if (omxError == OMX_ErrorResourcesLost
530aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            && internalError == DEAD_OBJECT) {
531aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
532aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
533aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    bool sendErrorReponse = true;
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(INITIALIZED);
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(CONFIGURED);
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
56203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
563aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
56403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
56503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
56603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
56703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
56803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
56903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
57003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
57103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
57203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
57303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
57403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
589575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
600575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (sendErrorReponse) {
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        sp<AMessage> response = new AMessage;
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        response->setInt32("err", UNKNOWN_ERROR);
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        response->postReply(mReplyID);
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatComponentAllocated:
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
619717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
621717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
6225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags |= kFlagIsSoftwareCodec;
6235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
6245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagIsSoftwareCodec;
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
627717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
6281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
6291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
6301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
6311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
6321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
6335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
6345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatComponentConfigured:
6385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
6405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(CONFIGURED);
6415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
6436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
6446507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
6455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
6465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                case ACodec::kWhatInputSurfaceCreated:
6507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
6517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    // response to ACodec::kWhatCreateInputSurface
6527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
6537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
6547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
6557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
6567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
6577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
6587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
6596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
6607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
6617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
6627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
6637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
6647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
6657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
6667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                case ACodec::kWhatSignaledInputEOS:
6687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
6697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    // response to ACodec::kWhatSignalEndOfInputStream
6707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
6717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
6727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
6737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
6747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
6757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
6767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
6777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
6787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatBuffersAllocated:
6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
6895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
6945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
695eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
696eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
697eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
698eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<ACodec::PortDescription> portDesc =
699eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        static_cast<ACodec::PortDescription *>(obj.get());
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
701eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
7025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
703eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
705eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
707eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
710ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
711ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                new ABuffer(info.mData->capacity());
712ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
713ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
726575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatOutputFormatChanged:
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if ((mFlags & kFlagIsSoftwareCodec)
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            && mNativeWindow != NULL) {
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (!strncasecmp("video/", mime.c_str(), 6)) {
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            delete mSoftRenderer;
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer = NULL;
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t width, height;
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("width", &width));
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("height", &height));
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t colorFormat;
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32(
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                        "color-format", &colorFormat));
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sp<MetaData> meta = new MetaData;
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyWidth, width);
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyHeight, height);
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyColorFormat, colorFormat);
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer =
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                new SoftwareRenderer(mNativeWindow, meta);
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
764e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
765e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
766e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
767e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
768e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
769e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
770e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
771e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
772e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
773e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatFillThisBuffer:
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
782c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
783c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
7898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
7908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
7918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
7928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
7938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
7948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
7958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
7968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
7978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
7988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
7998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
8018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
8028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
8038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8048ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            mFlags |= kFlagStickyError;
805575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
806575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
8078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
8088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
8098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
8108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
8118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (mFlags & kFlagDequeueInputPending) {
8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
8165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
818575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
819575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
8205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatDrainThisBuffer:
8255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
8275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
828c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
8315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8352d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
8362d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
8405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
8425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
843e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
844e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
845e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
846e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
848e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
854e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
857e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
860e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
861e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (mFlags & kFlagDequeueOutputPending) {
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
8645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
8665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
868575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
869575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
8705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
871575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
8725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatEOS:
8765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatShutdownCompleted:
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
884c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
885c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
886c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
887c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
888c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
889c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
8905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
8925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatFlushCompleted:
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, FLUSHING);
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(STARTED);
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalResume();
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
9330db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
9340db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
9741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
9757541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                status_t err = setNativeWindow(
9767541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    static_cast<NativeWindowWrapper *>(obj.get())
9777541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                        ->getSurfaceTextureClient());
9787541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
9797541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
9807541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    sp<AMessage> response = new AMessage;
9817541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    response->setInt32("err", err);
9827541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
9837541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    response->postReply(replyID);
9847541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
9851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
9861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
9877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                setNativeWindow(NULL);
9881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
9891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
9907541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
9917541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
9927541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
9931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
9941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
9951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
9991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
10098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
10157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
10167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            uint32_t replyID;
10177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
10187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
10207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
10217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                sp<AMessage> response = new AMessage;
10227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                response->setInt32("err", INVALID_OPERATION);
10237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                response->postReply(replyID);
10257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
10267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
10277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
10297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->initiateCreateInputSurface();
10307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
10317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
10327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != CONFIGURED) {
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1054c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1055c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1056aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1057aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1058aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            uint32_t replyID;
1060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1061c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1062c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            if (mState != INITIALIZED
1063c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    && mState != CONFIGURED && mState != STARTED) {
106403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // We may be in "UNINITIALIZED" state already without the
106503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
106603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
106703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
106803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
106903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1070aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // Similarly stopping a stopped MediaCodec should be benign.
1071c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
107203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                response->setInt32(
107303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                        "err",
1074aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mState == targetState ? OK : INVALID_OPERATION);
1075c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1076c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1077c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1078c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1079c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1080aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1081aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1082aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1083aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
1084aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1085aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1086aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1087aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1088c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1089aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1090aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1091aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1092aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1093c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
11046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
11056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                sp<AMessage> response = new AMessage;
11066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                response->setInt32("err", INVALID_OPERATION);
11076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                response->postReply(replyID);
11086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
11096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
11106507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", -EAGAIN);
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueInputTimedOut, id());
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", -EAGAIN);
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(mDequeueInputReplyID);
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", err);
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", -EAGAIN);
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueOutputTimedOut, id());
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", -EAGAIN);
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(mDequeueOutputReplyID);
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", err);
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
12557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
12567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            uint32_t replyID;
12577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
12587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != STARTED || (mFlags & kFlagStickyError)) {
12607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                sp<AMessage> response = new AMessage;
12617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                response->setInt32("err", INVALID_OPERATION);
12627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                response->postReply(replyID);
12647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
12657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
12667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
12687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
12697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
12707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
12717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
12981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if ((mState != STARTED && mState != FLUSHING)
1333972f2321583ef4094477271e0fc6a1d05a1a0eeaMartin Storsjo                    || (mFlags & kFlagStickyError)
1334972f2321583ef4094477271e0fc6a1d05a1a0eeaMartin Storsjo                    || mOutputFormat == NULL) {
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setMessage("format", mOutputFormat);
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1348496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
1349496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
1350496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
1351496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
1352496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
1353496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1354575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
1355575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
1356575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
1357575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
1358575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1359575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
1360575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
1361575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
1362575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1363717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
1364717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
1365717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            uint32_t replyID;
1366717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
1367717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1368717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
1369717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                sp<AMessage> response = new AMessage;
1370717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                response->setInt32("err", INVALID_OPERATION);
1371717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1372717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                response->postReply(replyID);
1373717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
1374717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
1375717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1376717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
1377717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
1378717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
1379717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
1380717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
1381717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1382a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
1383a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
1384a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            uint32_t replyID;
1385a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1386a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1387a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
1388a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
1389a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1390a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
1391a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1392a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> response = new AMessage;
1393a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            response->setInt32("err", err);
1394a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1395a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            response->postReply(replyID);
1396a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
1397a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
1398a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14048ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
14058ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
14068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
14088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
14098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
14108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
14118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
14128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
14138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
14158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
14168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
14178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    ALOGV("Found %u pieces of codec specific data.", mCSD.size());
14198ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
14208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
14228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
14238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    BufferInfo *info =
14258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex);
14268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
14288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
14298ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
14318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
14328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
14348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
14358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
14368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
14388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
14408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
14428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
14438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
14448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
14458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
14468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
14478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
14488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
14508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
14518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
14537541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
14587541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        setNativeWindow(NULL);
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
1464e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
1465e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
1466575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1467575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1470717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
1471717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        mComponentName.clear();
1472aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1473aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
1474aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
1475aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
1476aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
1477717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
1478717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
15037fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
15047fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15135778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void *bufferID;
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
15524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
15534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
15544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
15554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
15564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
15584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
15594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
15604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
15624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
15634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
15644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
15654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
15674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
15684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
15694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
15704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
15714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
15724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
15734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
15744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
15754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
15774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
15784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
15794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
15804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
15824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
15834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
15854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
15874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
15884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
15894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
15904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
15914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
15924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
16201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
16211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
1622ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1623ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16245b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
16255b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
16265b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
1627fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
16281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
16291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
16301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
16311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
16321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                info->mEncryptedData->base() + offset,
16334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
16344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
16355b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
16365b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
16371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1638fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
1639fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
1640ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1641ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1642fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
1643ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1644ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16452d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16485b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
16495b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mOwnedByClient = false;
16505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED) {
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16776aade6058521b0dbd35a9a4620f4d04f02f90444Marco Nelissen    if (render && (info->mData == NULL || info->mData->size() != 0)) {
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    info->mData->data(), info->mData->size(), NULL);
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mOwnedByClient = false;
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mOwnedByClient = true;
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17127541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow(
17131a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &surfaceTextureClient) {
17147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
17157541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (mNativeWindow != NULL) {
17177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
17187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
17197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
17217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
17227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
17237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
17247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow.clear();
17267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
17277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17287541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (surfaceTextureClient != NULL) {
17297541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
17307541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
17317541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
17337541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
17347541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
17357541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17367541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
17377541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
17387541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17397541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow = surfaceTextureClient;
17407541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
17417541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17427541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
17437541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
17447541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
1745575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
1746575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
1747575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
1748575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
1749575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1750575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if ((mFlags & (kFlagStickyError
1751575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
1752575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputFormatChanged))
1753575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
1754575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
1755575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
1756575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
1757575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
1758575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
1759575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1760a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
1761a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
1762a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
1763a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1764a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
1765a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
1766a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
1767a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1768a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
1769a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
1770a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1771a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
1772a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
1773a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1774e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
1775e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
1776e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
1777e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
1778e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1779e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
1780e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
1781e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
1782e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
1783e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
1784e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1785e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
1786e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
1788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
1789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
1791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
1792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
1793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
1794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
1795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
1796e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1797e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
1798e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    StringPrintf("csd-%u", csdIndex).c_str(), csd);
1799e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1800e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
1801e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
1804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
1805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
1807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
1808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
1809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
1810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
1813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
1816