MediaCodec.cpp revision e0381245dff04aa823a59aa8b85869eddab0f39f
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) {
11884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                for (size_t 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
355e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
356e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, id());
357e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
358e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
359e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
360e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
361e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
362e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
363e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
364e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
365e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
366e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
367e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
368e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
369717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
370717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> msg = new AMessage(kWhatGetName, id());
371717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
372717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
373717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
374717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
375717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
376717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
377717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
378717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
379717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
380717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
381717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
382717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4015778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatFlush, id());
4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
408496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
409496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
410496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
411496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
412496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
413496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
414575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
415575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
416575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
417575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
418575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
419575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4225778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(mDequeueInputReplyID);
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(mDequeueOutputReplyID);
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(replyID);
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
5085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatError:
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxError, internalError;
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("omx-error", &omxError));
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("err", &internalError));
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGE("Codec reported an error. "
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          "(omx error 0x%08x, internalError %d)",
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          omxError, internalError);
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
543aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    if (omxError == OMX_ErrorResourcesLost
544aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            && internalError == DEAD_OBJECT) {
545aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
546aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
547aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    bool sendErrorReponse = true;
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(INITIALIZED);
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(CONFIGURED);
5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
570c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
5715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
57603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
577aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
57803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
57903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
58003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
58103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
58203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
58303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
58403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
58503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
58603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
58703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
58803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
603575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
614575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (sendErrorReponse) {
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        sp<AMessage> response = new AMessage;
6215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        response->setInt32("err", UNKNOWN_ERROR);
6225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        response->postReply(mReplyID);
6245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatComponentAllocated:
6295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
6315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
6325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
633717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
6345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
635717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
6365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags |= kFlagIsSoftwareCodec;
6375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
6385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagIsSoftwareCodec;
6395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
641717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
6421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
6431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
6441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
6451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
6461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
6475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
6485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatComponentConfigured:
6525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
6545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(CONFIGURED);
6555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
6576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
6586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
659e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
660e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
661e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                case ACodec::kWhatInputSurfaceCreated:
6677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
6687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    // response to ACodec::kWhatCreateInputSurface
6697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
6707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
6717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
6727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
6737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
6747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
6757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
6766507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
6777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
6787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
6797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
6807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
6817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
6827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
6837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                case ACodec::kWhatSignaledInputEOS:
6857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
6867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    // response to ACodec::kWhatSignalEndOfInputStream
6877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
6887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
6897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
6907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
6917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
6927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
6937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
6947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
6957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
6975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatBuffersAllocated:
6985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
7015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
7035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
7075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
7115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
712eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
713eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
714eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
715eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<ACodec::PortDescription> portDesc =
716eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        static_cast<ACodec::PortDescription *>(obj.get());
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
718eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
720eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
722eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
724eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
727ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
728ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                new ABuffer(info.mData->capacity());
729ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
730ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
743575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatOutputFormatChanged:
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if ((mFlags & kFlagIsSoftwareCodec)
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            && mNativeWindow != NULL) {
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (!strncasecmp("video/", mime.c_str(), 6)) {
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            delete mSoftRenderer;
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer = NULL;
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t width, height;
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("width", &width));
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("height", &height));
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7666539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            int32_t cropLeft, cropTop, cropRight, cropBottom;
7676539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            CHECK(msg->findRect("crop",
7686539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                                &cropLeft, &cropTop, &cropRight, &cropBottom));
7696539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t colorFormat;
7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32(
7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                        "color-format", &colorFormat));
7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sp<MetaData> meta = new MetaData;
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyWidth, width);
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyHeight, height);
7776539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            meta->setRect(kKeyCropRect,
7786539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                                cropLeft, cropTop, cropRight, cropBottom);
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyColorFormat, colorFormat);
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer =
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                new SoftwareRenderer(mNativeWindow, meta);
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
787e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
788e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
789e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
790e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
791e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
792e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
793e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
794e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
795e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
796e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatFillThisBuffer:
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
804c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
805c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
806c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
8128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
8138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
8148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
8168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
8178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
8188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
8198ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
8208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
8228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
8248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
8258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
8268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            mFlags |= kFlagStickyError;
828575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
829575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
8308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
8318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
8328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
8338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
8348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (mFlags & kFlagDequeueInputPending) {
8365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
8405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
841575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
842575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatDrainThisBuffer:
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
851c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
852c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
853c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8582d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
8592d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
8605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
866e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
867e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
868e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
869e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
870e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
877e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
878e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
879e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
881e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
882e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
883e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
884e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (mFlags & kFlagDequeueOutputPending) {
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
8905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
891575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
892575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
8935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
894575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatEOS:
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatShutdownCompleted:
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
907c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
908c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
909c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
910c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
911c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
912c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatFlushCompleted:
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, FLUSHING);
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(STARTED);
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalResume();
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
9560db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
9570db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
9971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
9987541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                status_t err = setNativeWindow(
9997541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    static_cast<NativeWindowWrapper *>(obj.get())
10007541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                        ->getSurfaceTextureClient());
10017541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
10027541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
10037541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    sp<AMessage> response = new AMessage;
10047541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    response->setInt32("err", err);
10057541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
10067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    response->postReply(replyID);
10077541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
10081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
10091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
10107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                setNativeWindow(NULL);
10111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
10121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
10137541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
10147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
10157541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
10161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
10171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
10181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
10221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1028e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
10328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
10387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
10397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            uint32_t replyID;
10407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
10417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
10437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
10447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                sp<AMessage> response = new AMessage;
10457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                response->setInt32("err", INVALID_OPERATION);
10467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                response->postReply(replyID);
10487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
10497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
10507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
10527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->initiateCreateInputSurface();
10537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
10547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
10557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != CONFIGURED) {
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1077c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1078c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1079aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1080aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1081aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1082c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            uint32_t replyID;
1083c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1084c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1085c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            if (mState != INITIALIZED
1086c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    && mState != CONFIGURED && mState != STARTED) {
108703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // We may be in "UNINITIALIZED" state already without the
108803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
108903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
109003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
109103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
109203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1093aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // Similarly stopping a stopped MediaCodec should be benign.
1094c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
109503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                response->setInt32(
109603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                        "err",
1097aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mState == targetState ? OK : INVALID_OPERATION);
1098c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1099c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1100c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1101c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1102c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1103aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1104aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1105aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1106aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
1107aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1108aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1109aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1110aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1111c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1112aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1113aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1114aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1115aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1116c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
11276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
11286507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                sp<AMessage> response = new AMessage;
11296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                response->setInt32("err", INVALID_OPERATION);
11306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                response->postReply(replyID);
11316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
11326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
11336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", -EAGAIN);
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueInputTimedOut, id());
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", -EAGAIN);
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(mDequeueInputReplyID);
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", err);
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", -EAGAIN);
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueOutputTimedOut, id());
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", -EAGAIN);
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(mDequeueOutputReplyID);
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", err);
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
12787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
12797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            uint32_t replyID;
12807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
12817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != STARTED || (mFlags & kFlagStickyError)) {
12837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                sp<AMessage> response = new AMessage;
12847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                response->setInt32("err", INVALID_OPERATION);
12857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                response->postReply(replyID);
12877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
12887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
12897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
12917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
12927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
12937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
12947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1320ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
13211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1322ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
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            mReplyID = replyID;
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1350e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
1353e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
1354e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1355e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1359e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
1360e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                 mState != STARTED && mState != FLUSHING)
1361972f2321583ef4094477271e0fc6a1d05a1a0eeaMartin Storsjo                    || (mFlags & kFlagStickyError)
1362e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
1371e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1376496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
1377496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
1378496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
1379496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
1380496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
1381496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1382575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
1383575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
1384575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
1385575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
1386575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1387575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
1388575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
1389575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
1390575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1391717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
1392717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
1393717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            uint32_t replyID;
1394717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
1395717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1396717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
1397717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                sp<AMessage> response = new AMessage;
1398717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                response->setInt32("err", INVALID_OPERATION);
1399717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1400717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                response->postReply(replyID);
1401717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
1402717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
1403717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1404717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
1405717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
1406717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
1407717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
1408717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
1409717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1410a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
1411a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
1412a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            uint32_t replyID;
1413a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1414a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1415a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
1416a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
1417a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1418a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
1419a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1420a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> response = new AMessage;
1421a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            response->setInt32("err", err);
1422a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1423a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            response->postReply(replyID);
1424a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
1425a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
1426a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14328ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
14338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
14348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
14368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
14378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
14388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
14398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
14408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
14418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
14438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
14448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
14458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    ALOGV("Found %u pieces of codec specific data.", mCSD.size());
14478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
14488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
14508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
14518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    BufferInfo *info =
14538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        &mPortBuffers[kPortIndexInput].editItemAt(bufferIndex);
14548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
14568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
14578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
14598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
14608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
14628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
14638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
14648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
14668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
14688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
14708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
14718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
14728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
14738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
14748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
14758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
14768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
14788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
14798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14805778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
14817541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
14867541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        setNativeWindow(NULL);
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
1492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
1493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
1494575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1495575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1498717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
1499717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        mComponentName.clear();
1500aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1501aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
1502aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
1503aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
1504aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
1505717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
1506717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15125778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15175778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
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->mNotify != NULL) {
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
15317fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
15327fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15415778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void *bufferID;
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
15804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
15814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
15824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
15834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
15844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
15864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
15874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
15884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
15904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
15914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
15924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
15934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
15944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
15954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
15964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
15974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
15984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
15994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
16004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
16014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
16024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
16034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
16054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
16064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
16074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
16084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
16104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
16114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
16134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
16154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
16164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
16174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
16184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
16194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
16204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
16481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
16491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
1650ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1651ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16525b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
16535b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
16545b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
1655fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
16561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
16571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
16581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
16591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
16601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                info->mEncryptedData->base() + offset,
16614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
16624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
16635b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
16645b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
16651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1666fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
1667fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
1668ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1669ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1670fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
1671ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1672ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
16732d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
16775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mOwnedByClient = false;
16785b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED) {
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
170579ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    info->mData->data(), info->mData->size(), NULL);
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mOwnedByClient = false;
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mOwnedByClient = true;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17407541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow(
17411a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &surfaceTextureClient) {
17427541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
17437541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17447541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (mNativeWindow != NULL) {
17457541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
17467541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
17477541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17487541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
17497541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
17507541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
17517541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
17527541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17537541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow.clear();
17547541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
17557541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17567541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (surfaceTextureClient != NULL) {
17577541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
17587541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
17597541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17607541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
17617541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
17627541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
17637541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17647541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
17657541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
17667541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17677541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow = surfaceTextureClient;
17687541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
17697541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17707541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
17717541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
17727541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
1773575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
1774575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
1775575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
1776575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
1777575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1778575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if ((mFlags & (kFlagStickyError
1779575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
1780575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputFormatChanged))
1781575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
1782575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
1783575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
1784575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
1785575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
1786575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
1787575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1788a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
1789a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
1790a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
1791a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1792a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
1793a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
1794a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
1795a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1796a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
1797a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
1798a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1799a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
1800a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
1801a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1802e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
1803e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
1804e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
1805e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
1806e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1807e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
1808e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
1809e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
1810e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
1811e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
1812e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1813e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
1814e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1815e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
1816e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
1817e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1818e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
1819e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
1820e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
1821e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
1822e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
1823e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
1824e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1825e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
1826e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    StringPrintf("csd-%u", csdIndex).c_str(), csd);
1827e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1828e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
1829e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1830e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1831e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
1832e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
1833e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1834e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
1835e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
1836e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
1837e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
1838e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
1839e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1840e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
1841e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
1842e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
1844