MediaCodec.cpp revision 5778822d86b0337407514b9372562b86edfa91cd
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/*
25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright 2012, The Android Open Source Project
35778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License.
65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at
75778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
85778822d86b0337407514b9372562b86edfa91cdAndreas Huber *     http://www.apache.org/licenses/LICENSE-2.0
95778822d86b0337407514b9372562b86edfa91cdAndreas Huber *
105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software
115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and
145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License.
155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */
165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0
185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "MediaCodec"
195778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <utils/Log.h>
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
215778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaCodec.h>
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/SoftwareRenderer.h"
245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
255778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <gui/SurfaceTextureClient.h>
265778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
275778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
285778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
315778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
345778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
365778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
375778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ALooper> &looper, const char *mime, bool encoder) {
395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (codec->init(mime, true /* nameIsType */, encoder) != OK) {
415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return NULL;
425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return codec;
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
485778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ALooper> &looper, const char *name) {
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) {
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return NULL;
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return codec;
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
585778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
605778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
615778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mCodec(new ACodec),
625778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
635778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
645778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
655778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
665778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
675778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputReplyID(0) {
685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
705778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
745778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
755778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool needDedicatedLooper = false;
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType && !strncasecmp(name, "video/", 6)) {
975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        needDedicatedLooper = true;
985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (!nameIsType && !strncmp(name, "OMX.TI.DUCATI1.VIDEO.", 21)) {
995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        needDedicatedLooper = true;
1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (needDedicatedLooper) {
1035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
1045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
1055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
1065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
1075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
1105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
1115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
1125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
1155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
1175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatInit, id());
1195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
1205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
1215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
1235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
1245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
1315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
1325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<SurfaceTextureClient> &nativeWindow,
1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
1345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
1385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nativeWindow != NULL) {
1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (!(mFlags & kFlagIsSoftwareCodec)) {
1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->setObject(
1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    "native-window",
1435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new NativeWindowWrapper(nativeWindow));
1445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mNativeWindow = nativeWindow;
1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1535778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatStart, id());
1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1605778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
1615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatStop, id());
1625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
1685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
1695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
1705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
1715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
1725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
1735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
1795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
1825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
1855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
1865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
1875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
1895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
1905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
1925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
2005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
2015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
2025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
2035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
2045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
2055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
2065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
2075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
2085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
2115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
2135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
2165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
2175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
2185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
2195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
2225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
2475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
2485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
2515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatFlush, id());
2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2825778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
2865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(mDequeueInputReplyID);
2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(mDequeueOutputReplyID);
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<AMessage> response = new AMessage;
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->postReply(replyID);
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
3245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3305778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3855778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatError:
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxError, internalError;
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("omx-error", &omxError));
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("err", &internalError));
3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGE("Codec reported an error. "
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          "(omx error 0x%08x, internalError %d)",
4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          omxError, internalError);
4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    bool sendErrorReponse = true;
4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(INITIALIZED);
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(CONFIGURED);
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (sendErrorReponse) {
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        sp<AMessage> response = new AMessage;
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        response->setInt32("err", UNKNOWN_ERROR);
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        response->postReply(mReplyID);
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatComponentAllocated:
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
4715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    AString componentName;
4735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findString("componentName", &componentName));
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (componentName.startsWith("OMX.google.")) {
4765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags |= kFlagIsSoftwareCodec;
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagIsSoftwareCodec;
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatComponentConfigured:
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(CONFIGURED);
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatBuffersAllocated:
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
5085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    for (size_t i = 0;; ++i) {
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString name = StringPrintf("buffer-id_%d", i);
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        void *bufferID;
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (!msg->findPointer(name.c_str(), &bufferID)) {
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        name = StringPrintf("data_%d", i);
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        sp<RefBase> obj;
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findObject(name.c_str(), &obj));
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mBufferID = bufferID;
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mData = static_cast<ABuffer *>(obj.get());
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
5385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatOutputFormatChanged:
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if ((mFlags & kFlagIsSoftwareCodec)
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            && mNativeWindow != NULL) {
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
5505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
5515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (!strncasecmp("video/", mime.c_str(), 6)) {
5535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            delete mSoftRenderer;
5545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer = NULL;
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t width, height;
5575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("width", &width));
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("height", &height));
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t colorFormat;
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32(
5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                        "color-format", &colorFormat));
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sp<MetaData> meta = new MetaData;
5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyWidth, width);
5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyHeight, height);
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyColorFormat, colorFormat);
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer =
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                new SoftwareRenderer(mNativeWindow, meta);
5715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mFlags |= kFlagOutputFormatChanged;
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatFillThisBuffer:
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (mState == FLUSHING) {
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
5875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (mFlags & kFlagDequeueInputPending) {
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
5935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
5955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatDrainThisBuffer:
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (mState == FLUSHING) {
6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    sp<RefBase> obj;
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findObject("buffer", &obj));
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (mFlags & kFlagDequeueOutputPending) {
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
6215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
6225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
6235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
6245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatEOS:
6285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
6305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
6315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatShutdownCompleted:
6355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, STOPPING);
6375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(UNINITIALIZED);
6385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
6405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                case ACodec::kWhatFlushCompleted:
6445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
6455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, FLUSHING);
6465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(STARTED);
6475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalResume();
6495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
6515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
6525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
6535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
6555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
6565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
6575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
6585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
6665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
6675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
6685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
6705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
6715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
6725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
6745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
6805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findInt32("nameIsType", &nameIsType)) {
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                nameIsType = false;
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
6885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
6945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
6955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
6975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
6985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
7015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
7025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
7035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
7075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
7115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
7125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(CONFIGURING);
7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != CONFIGURED) {
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    && mState != CONFIGURED && mState != STARTED) {
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STOPPING);
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateShutdown();
7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", -EAGAIN);
7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueInputTimedOut, id());
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
8165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
8195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
8205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
8245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", -EAGAIN);
8275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(mDequeueInputReplyID);
8285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
8305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
8315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
8365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
8405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
8425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", err);
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
8585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
8595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
8665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
8685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
8695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", -EAGAIN);
8705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
8715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
8725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
8755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
8765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueOutputTimedOut, id());
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
8825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
8905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
8915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
8935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
8945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", -EAGAIN);
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(mDequeueOutputReplyID);
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
9095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setInt32("err", err);
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                dstBuffers->push_back(info.mData);
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if ((mState != STARTED && mState != FLUSHING)
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    || (mFlags & kFlagStickyError)) {
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> response = new AMessage;
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->setInt32("err", INVALID_OPERATION);
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                response->postReply(replyID);
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->setMessage("format", mOutputFormat);
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10075778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (newState == UNINITIALIZED) {
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mNativeWindow.clear();
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10255778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10305778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                msg->setInt32("err", ERROR_END_OF_STREAM);
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    void *bufferID;
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findPointer("buffer-id", &bufferID));
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("size", &size));
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
11075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mOwnedByClient = false;
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->setObject("buffer", info->mData);
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED) {
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (render) {
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    info->mData->data(), info->mData->size(), NULL);
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mOwnedByClient = false;
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mOwnedByClient = true;
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
1186