MediaCodec.cpp revision c5619c7a6dcc1137fde7520351ad5284e3e958ab
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>
20fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#include <inttypes.h>
215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaCodec.h>
235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
245778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/SoftwareRenderer.h"
255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
261a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
27ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
285778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
315b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
32ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
356f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
36e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
395778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h>
405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include "include/avc_utils.h"
42e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
435778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
465778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ALooper> &looper, const char *mime, bool encoder) {
485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (codec->init(mime, true /* nameIsType */, encoder) != OK) {
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return NULL;
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return codec;
545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
575778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ALooper> &looper, const char *name) {
595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) {
615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return NULL;
625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return codec;
655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
675778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
695778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
7092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
725778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
735778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
745778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
755778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
765778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
776507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
786507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mHaveInputSurface(false) {
795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
815778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
855778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
101c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static
102c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::PostReplyWithError(int32_t replyID, int32_t err) {
103c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
104c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->setInt32("err", err);
105c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
106c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
107c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
1095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
1105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
1115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
1125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
11392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar    mCodec = new ACodec;
1145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool needDedicatedLooper = false;
1155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType && !strncasecmp(name, "video/", 6)) {
1165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        needDedicatedLooper = true;
1176f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
1186f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
1196f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
1206f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
1216f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
1226f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        const MediaCodecList *mcl = MediaCodecList::getInstance();
1236f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
1246f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
1256f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            Vector<AString> types;
1266f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            if (mcl->getSupportedTypes(codecIdx, &types) == OK) {
12784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                for (size_t i = 0; i < types.size(); i++) {
1286f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                    if (types[i].startsWith("video/")) {
1296f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                        needDedicatedLooper = true;
1306f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                        break;
1316f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                    }
1326f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
1336f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
1346f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (needDedicatedLooper) {
1385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
1395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
1475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
1505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
1525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatInit, id());
1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
1565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
1585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
1595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
165c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
166c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetCallback, id());
167c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
168c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
169c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
170c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
171c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
172c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
1751a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &nativeWindow,
1761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
1825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nativeWindow != NULL) {
1841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setObject(
1851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                "native-window",
1861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new NativeWindowWrapper(nativeWindow));
1871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
1881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
1901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
1987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
1997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
2007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
2027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
2037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
2047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
2057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
2067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
2077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
2087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
2097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
2107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
2117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
2127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
2137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
2147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
2157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
2167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2175778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
2185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatStart, id());
2195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatStop, id());
2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
231c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
232c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatRelease, id());
233c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
234c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
235c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
236c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
237c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
2435b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
2445b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
2455b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
2465b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
2475b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
2485b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
2555b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
2624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
2634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
2644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
2654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
2664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
2674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
2684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
2694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
2705b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
2715b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
2725b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
2735b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
2745b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
2755b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
2774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
2784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
2794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
2804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
2814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
2824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
2834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
2844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
2854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
2865b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
2874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
2884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
2895b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
2905b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2915b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
2924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
2934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
343fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
344fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
345fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
346fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
347fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
348fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
349fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
350fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
351fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
352fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
3627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
3637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
3657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
3667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
3677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
382e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
383e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, id());
384e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
385e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
386e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
387e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
388e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
389e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
390e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
391e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
392e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
393e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
394e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
395e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
396717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
397717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> msg = new AMessage(kWhatGetName, id());
398717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
399717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
400717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
401717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
402717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
403717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
404717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
405717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
406717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
407717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
408717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
409717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4287bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
4297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
4307bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
4317bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
4327bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
4337bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
4347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
4357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
4367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
4377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
4387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
4397bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
4407bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
4417bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
4427bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
4437bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
4447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
4457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
4467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
4477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
4487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
4497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
4507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (mState != STARTED) {
4517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
4527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
4537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
4547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
4557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
4567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
4577bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
4587bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
4597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
4607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
4617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *buffer = info.mData;
4627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
4637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
4647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
4657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
4667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
4677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatFlush, id());
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
475496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
476496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
477496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
478496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
479496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
480496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
481575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
482575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
483575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
484575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
485575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
486575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
491c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
499c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5075778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
5085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
511c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
5715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
59292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxError, internalError;
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("omx-error", &omxError));
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("err", &internalError));
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGE("Codec reported an error. "
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          "(omx error 0x%08x, internalError %d)",
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          omxError, internalError);
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
602aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    if (omxError == OMX_ErrorResourcesLost
603aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            && internalError == DEAD_OBJECT) {
604aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
605aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
606aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    bool sendErrorReponse = true;
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(INITIALIZED);
6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
6235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(CONFIGURED);
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
629c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
6305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
6325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
6335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
63503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
636aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
63703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
63803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
63903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
64003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
64103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
64203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
64303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
64403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
64503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
64603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
64703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
6485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
6525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
6545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
6585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
662575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
665c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
666c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
667c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                                onError(0, omxError);
668c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
669ec5f7cc4756d389505e761b9d803a1a3a46b64d7Lajos Molnar                            setState(UNINITIALIZED);
6705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
6745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
6765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
678575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
679c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
680c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
681c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                                onError(0, omxError);
682c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
683ec5f7cc4756d389505e761b9d803a1a3a46b64d7Lajos Molnar                            setState(UNINITIALIZED);
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (sendErrorReponse) {
689c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        PostReplyWithError(mReplyID, UNKNOWN_ERROR);
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
69492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
6955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
6975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
6985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
699717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
701717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
7025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags |= kFlagIsSoftwareCodec;
7035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagIsSoftwareCodec;
7055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
707717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
7081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
7091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
7101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
7111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
7121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
7135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
71792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(CONFIGURED);
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
7236507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
7246507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
727e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
73292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
7337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
73492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
7357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
7367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
7377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
7387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
7397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
7407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
7417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
7426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
7437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
7447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
7457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
7467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
7477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
7487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
7497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
75092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
7517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
75292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
7537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
7547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
7557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
7567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
7577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
7587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
7597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
7607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
7617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
76392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
7657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
779eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
780eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
781eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
78292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
78392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
785eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
787eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
789eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
791eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
794ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
795ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                new ABuffer(info.mData->capacity());
796ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
797ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
810575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
81692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
8195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if ((mFlags & kFlagIsSoftwareCodec)
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            && mNativeWindow != NULL) {
8225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
8245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (!strncasecmp("video/", mime.c_str(), 6)) {
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            delete mSoftRenderer;
8275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer = NULL;
8285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t width, height;
8305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("width", &width));
8315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("height", &height));
8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8336539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            int32_t cropLeft, cropTop, cropRight, cropBottom;
8346539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            CHECK(msg->findRect("crop",
8356539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                                &cropLeft, &cropTop, &cropRight, &cropBottom));
8366539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t colorFormat;
8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32(
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                        "color-format", &colorFormat));
8405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sp<MetaData> meta = new MetaData;
8425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyWidth, width);
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyHeight, height);
8446539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            meta->setRect(kKeyCropRect,
8456539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                                cropLeft, cropTop, cropRight, cropBottom);
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyColorFormat, colorFormat);
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer =
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                new SoftwareRenderer(mNativeWindow, meta);
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
854e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
857e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
860c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
861c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
862e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
863e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
865e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
8665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
86992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
8705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
8725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
873c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
874c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
875c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
8765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
8818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
8828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
8838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
8858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
8868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
8878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
8888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
8898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
8918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
8938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
8948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
8958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
8968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            mFlags |= kFlagStickyError;
897575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
898575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
8998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
9008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
9018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
9028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
9038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
904c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
905c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onInputBufferAvailable();
906c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
912575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
913575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
91892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
922c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
923c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
924c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9292d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
9302d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
937e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
938e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
939e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
940e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
941e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
942e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
943e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
944e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
945e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
946e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
947e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
948e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
949e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
950e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
951e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
952e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
953c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
954c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
955c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
956c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
957c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
958e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
959e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
960c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
961c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
962c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
968575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
969575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
971575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
97592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
98292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
984c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
985c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
986c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
987c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
988c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
989c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
99592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, FLUSHING);
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(STARTED);
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalResume();
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1018c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
10300db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
10310db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1048c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1049c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
1050c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            uint32_t replyID;
1051c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1052c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1053c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1054c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
1055c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == STARTED) {
1056c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // callback can't be set after codec is started,
1057c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1058c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1059c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1060c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1061c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1062c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1063c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1064c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1065c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1066c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1067c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1068c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1069c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1070c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1071c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1072c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1073c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1074c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1075c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1076c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1077c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1078c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1079c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1086c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
11001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
11017541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                status_t err = setNativeWindow(
11027541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    static_cast<NativeWindowWrapper *>(obj.get())
11037541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                        ->getSurfaceTextureClient());
11047541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
11057541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1106c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
11077541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
11081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
11091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
11107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                setNativeWindow(NULL);
11111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
11121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
11137541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
11147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
11157541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
11161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
11171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
11181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
11221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1128e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
11328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
11387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
11397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            uint32_t replyID;
11407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
11417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
11427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
11437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1144c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
11457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
11467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
11477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
11487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
11497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->initiateCreateInputSurface();
11507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
11517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
11527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != CONFIGURED) {
1159c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1171c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1172c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1173aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1174aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1175aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1176c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            uint32_t replyID;
1177c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1178c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1179c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            if (mState != INITIALIZED
1180c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    && mState != CONFIGURED && mState != STARTED) {
118103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // We may be in "UNINITIALIZED" state already without the
118203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
118303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
118403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
118503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
118603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1187aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // Similarly stopping a stopped MediaCodec should be benign.
1188c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
118903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                response->setInt32(
119003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                        "err",
1191aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mState == targetState ? OK : INVALID_OPERATION);
1192c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1193c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1194c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1195c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1196c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1197aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1198aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1199aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1200aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
1201aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1202aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1203aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1204aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1205c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1206aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1207aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1208aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1209aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1210c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1220c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1221c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1222c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1223c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1224c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1225c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
12266507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
12276507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1228c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
12296507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
12306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
12316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1240c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueInputTimedOut, id());
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1269c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1282c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1288c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1297c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1298c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1299c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1300c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1301c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1302c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1311c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueOutputTimedOut, id());
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1340c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1353c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1359c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
13647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
13657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            uint32_t replyID;
13667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
13677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
13687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1369c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
13707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
13717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
13727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
13737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
13747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
13757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
13767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
13777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1384c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1400ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
14011bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1402ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1415c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1427e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
1430e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
1431e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1432e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1436e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
1437e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                 mState != STARTED && mState != FLUSHING)
1438972f2321583ef4094477271e0fc6a1d05a1a0eeaMartin Storsjo                    || (mFlags & kFlagStickyError)
1439e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
1440c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
1445e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1450496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
1451496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
1452496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
1453496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
1454496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
1455496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1456575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
1457575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
1458575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
1459575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
1460575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1461575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
1462575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
1463575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
1464575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1465717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
1466717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
1467717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            uint32_t replyID;
1468717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
1469717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1470717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
1471c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1472717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
1473717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
1474717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1475717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
1476717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
1477717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
1478717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
1479717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
1480717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1481a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
1482a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
1483a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            uint32_t replyID;
1484a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1485a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1486a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
1487a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
1488a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1489a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
1490a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1491c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
1492a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
1493a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
1494a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15008ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
15018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
15028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
15048ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
15058ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
15068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
15078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
15088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
15098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
15118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
15128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
15138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1514a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
15158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
15168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
15188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
15198ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15207bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
15217bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
15228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
15248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
15258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
15278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
15288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15298ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
15308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
15318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
15328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
15348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
15368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
15388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
15398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
15408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
15418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
15428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
15438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
15448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
15468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
15478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15485778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
15497541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
15547541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        setNativeWindow(NULL);
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
1560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
1561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
1562c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
1563575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1564575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
1565c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1568717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
1569717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        mComponentName.clear();
1570aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1571aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
1572aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
1573aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
1574aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
1575717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
1576717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15825778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15875778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
15897bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
16027fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
16037fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16125778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1616609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
1617609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16504b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
16514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
16524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
16534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
16544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
16554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
16574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
16584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
16594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
16614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
16624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
16634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
16644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
16664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
16674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
16684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
16694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
16704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
16714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
16724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
16734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
16744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
16764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
16774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
16784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
16794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
16814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
16824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
16844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
16864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
16874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
16884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
16894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
16904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
16914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
17191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
17201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
1721ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1722ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17235b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
17245b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
17255b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
1726fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
17271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
17281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
17291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
17301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
17311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                info->mEncryptedData->base() + offset,
17324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
17334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
17345b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
17355b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
17361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1737fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
1738fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
1739ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1740ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1741fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
1742ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1743ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
17447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
17457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
17467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
17477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
17487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
17492d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17525b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
17535b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED) {
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17807bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
17817bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
17827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
17837bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
17847bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
17857bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
178679ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1789fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
1790fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (msg->findInt64("timestampNs", &timestampNs)) {
1791fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            info->mNotify->setInt64("timestampNs", timestampNs);
1792fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        } else {
1793fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
1794fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
1795fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
1796fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
1797fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
1798fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
179947aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
1800fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
1801fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
1802fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
1803fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
1804fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
1807fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                    info->mData->data(), info->mData->size(), timestampNs, NULL);
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
18317bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
18327bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
18337bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mFormat = portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
18347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
18357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18407541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow(
18411a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &surfaceTextureClient) {
18427541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
18437541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18447541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (mNativeWindow != NULL) {
18457541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
18467541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
18477541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18487541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
18497541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
18507541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
18517541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
18527541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18537541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow.clear();
18547541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
18557541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18567541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (surfaceTextureClient != NULL) {
18577541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
18587541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
18597541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18607541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
18617541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
18627541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
18637541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18647541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
18657541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
18667541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18677541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow = surfaceTextureClient;
18687541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
18697541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18707541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
18717541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
18727541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
1873c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
1874c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
1875c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
1876c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
1877c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
1878c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
1879c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
1880c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
1881c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
1882c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1883c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
1884c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
1885c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
1886c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
1887c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
1888c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
1889c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
1890c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
1891c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
1892c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
1893c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1894c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
1895c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
1896c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1897c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
1898c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1899c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
1900c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
1901c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1902c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
1903c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
1904c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
1905c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1906c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1907c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
1908c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1909c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
1910c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
1911c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1912c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1913c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
1914c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1915c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
1916c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
1917c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
1918c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1919c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onError(int32_t actionCode, status_t err) {
1920c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
1921c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
1922c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
1923c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("actionCode", actionCode);
1924c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
1925c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1926c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
1927c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
1928c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
1929c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1930c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
1931c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
1932c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
1933c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
1934c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
1935c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
1936c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
1937c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
1938c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1939c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1940575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
1941575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
1942575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
1943575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
1944575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1945575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if ((mFlags & (kFlagStickyError
1946575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
1947575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputFormatChanged))
1948575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
1949575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
1950575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
1951575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
1952575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
1953575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
1954575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1955a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
1956a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
1957a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
1958a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1959a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
1960a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
1961a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
1962a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1963a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
1964a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
1965a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1966a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
1967a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
1968a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1969e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
1970e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
1971e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
1972e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
1973e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1974e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
1975e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
1976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
1977e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
1978e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
1979e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1980e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
1981e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1982e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
1983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
1984e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1985e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
1986e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
1987e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
1988e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
1989e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
1990e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
1991e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1992e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
1993e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    StringPrintf("csd-%u", csdIndex).c_str(), csd);
1994e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1995e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
1996e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
1997e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1998e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
1999e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2000e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2001e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2002e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2003e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2004e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2005e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2006e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2007e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2008e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2009e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2011