MediaCodec.cpp revision 03c556ae1eb409ad088c49037e185946c54e1d25
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"
19fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#include <inttypes.h>
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include "include/avc_utils.h"
225778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/SoftwareRenderer.h"
235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IBatteryStats.h>
252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h>
261a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
27ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
285778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
295778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
315b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
32ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
352606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
366f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
37e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
395778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
405778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h>
412606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
422606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
44e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
455778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    BatteryNotifier();
492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartVideo();
512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopVideo();
522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartAudio();
532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopAudio();
542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate:
562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mVideoRefCount;
572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mAudioRefCount;
582606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    sp<IBatteryStats> mBatteryStatService;
592606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang};
602606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
612606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
632606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() :
642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount(0),
652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount(0) {
662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    // get battery service
672606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    const sp<IServiceManager> sm(defaultServiceManager());
682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (sm != NULL) {
692606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        const String16 name("batterystats");
702606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatService = interface_cast<IBatteryStats>(sm->getService(name));
712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mBatteryStatService == NULL) {
722606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            ALOGE("batterystats service unavailable!");
732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
742606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
752606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
762606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() {
782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatService->noteStartVideo(AID_MEDIA);
802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount++;
822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() {
852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0) {
862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount--;
912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0 && mBatteryStatService != NULL) {
922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatService->noteStopVideo(AID_MEDIA);
932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() {
972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatService->noteStartAudio(AID_MEDIA);
992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount++;
1012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() {
1042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mAudioRefCount == 0) {
1052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
1062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
1072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount--;
1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mAudioRefCount == 0 && mBatteryStatService != NULL) {
1112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatService->noteStopAudio(AID_MEDIA);
1122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1145778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1155778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
1165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ALooper> &looper, const char *mime, bool encoder) {
1175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
1185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (codec->init(mime, true /* nameIsType */, encoder) != OK) {
1195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return NULL;
1205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return codec;
1235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1255778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1265778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
1275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ALooper> &looper, const char *name) {
1285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
1295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (codec->init(name, false /* nameIsType */, false /* encoder */) != OK) {
1305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return NULL;
1315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return codec;
1345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1365778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
1385778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
13992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
1407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
1432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
1442606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
1475778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
1486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
1496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mHaveInputSurface(false) {
1505778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1525778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
1535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1565778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1575778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
1585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
1595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
1605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
1625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
1635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
1665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
1675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
1685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
1705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
172c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static
173c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::PostReplyWithError(int32_t replyID, int32_t err) {
174c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
175c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->setInt32("err", err);
176c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
177c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
178c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1795778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
180671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
181671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
182671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
183671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
184671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
1855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
1865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
1875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
1885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
18992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar    mCodec = new ACodec;
1905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool needDedicatedLooper = false;
1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType && !strncasecmp(name, "video/", 6)) {
1925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        needDedicatedLooper = true;
1936f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
1946f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
1956f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
1966f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
1976f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
1986f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        const MediaCodecList *mcl = MediaCodecList::getInstance();
1996f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
2006f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
2016f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            Vector<AString> types;
2026f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            if (mcl->getSupportedTypes(codecIdx, &types) == OK) {
20384333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber                for (size_t i = 0; i < types.size(); i++) {
2046f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                    if (types[i].startsWith("video/")) {
2056f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                        needDedicatedLooper = true;
2066f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                        break;
2076f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                    }
2086f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
2096f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
2106f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
2115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (needDedicatedLooper) {
2145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
2155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
2165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
2175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
2185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
2225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, id()));
2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatInit, id());
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
241c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
242c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetCallback, id());
243c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
244c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
245c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
246c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
247c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
248c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
2505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
2511a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &nativeWindow,
2521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatConfigure, id());
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nativeWindow != NULL) {
2601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setObject(
2611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                "native-window",
2621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new NativeWindowWrapper(nativeWindow));
2631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
2641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
2661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
2747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
2757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, id());
2767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
2787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
2797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
2807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
2817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
2827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
2837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
2847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
2857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
2867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
2877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
2887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
2897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
2907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
2917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
2927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatStart, id());
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatStop, id());
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
307c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
308c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> msg = new AMessage(kWhatRelease, id());
309c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
310c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
311c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
312c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
313c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
314671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
315671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
316671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
317671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
318671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
319671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
320671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
321671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
322671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
323671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
324671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
325671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
326671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
327671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
328671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
329671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
330671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
331671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
332671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
333671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
334671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
335671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
336671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
337671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
338671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
339671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
340671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
341671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
342671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
343671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        err = init(mInitName.c_str(), mInitNameIsType, mInitIsEncoder);
344671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
345671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
346671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
347671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
3535b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
3545b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
3555b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
3565b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
3575b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
3585b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
3655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
3724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
3734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
3744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
3754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
3764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
3774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
3784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
3794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
3805b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
3815b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
3825b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
3835b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
3845b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
3855b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
3864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
3874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
3884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
3894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
3904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
3914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
3924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
3934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
3944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
3954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
3965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
3974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
3984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
3995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
4005b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
4015b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
4024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
4034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
4045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, id());
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, id());
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
453fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
454fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
455fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
456fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
457fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
458fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
459fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
460fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
461fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
462fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, id());
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
4727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, id());
4737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
4757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
4767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
4777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, id());
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
492e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
493e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, id());
494e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
495e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
496e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
497e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
498e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
499e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
500e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
501e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
502e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
503e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
504e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
505e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
506717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
507717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> msg = new AMessage(kWhatGetName, id());
508717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
509717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
510717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
511717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
512717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
513717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
514717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
515717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
516717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
517717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
518717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
519717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatGetBuffers, id());
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
5397bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
5407bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
5417bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
5427bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
5437bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
5447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
5457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
5467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
5477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
5487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
5497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
5507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
5517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
5527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
5537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
5547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
5557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
5567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
5577bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
5587bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
5597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
5607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (mState != STARTED) {
5617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
5627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
5637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
5647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
5657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
5667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
5677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
5687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
5697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
5707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
5717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *buffer = info.mData;
5727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
5737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
5747bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
5757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
5767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
5777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> msg = new AMessage(kWhatFlush, id());
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
585496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
586496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    (new AMessage(kWhatRequestIDRFrame, id()))->post();
587496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
588496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
589496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
590496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
591575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
592575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
593575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
594575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
595575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
596575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5995778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
601c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
6065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
609c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueInputBuffer(uint32_t replyID, bool newRequest) {
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
621c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
6225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
6235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
6285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
6295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
6305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
6335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
6345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
6355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
6375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6395778822d86b0337407514b9372562b86edfa91cdAndreas Huberbool MediaCodec::handleDequeueOutputBuffer(uint32_t replyID, bool newRequest) {
6405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
6415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED
6435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (mFlags & kFlagStickyError)
6445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
6455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
6465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
6475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
6485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
6495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
6505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
6515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
6525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
6535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
6545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
6565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
6575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
6585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
6655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
6665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
6685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
6695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
6715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
6735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
6745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
6765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
6805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6945778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
6955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
6965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
6975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
6985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
6995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
70292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
7035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxError, internalError;
7055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("omx-error", &omxError));
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("err", &internalError));
7075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGE("Codec reported an error. "
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          "(omx error 0x%08x, internalError %d)",
7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          omxError, internalError);
7115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
712aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    if (omxError == OMX_ErrorResourcesLost
713aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            && internalError == DEAD_OBJECT) {
714aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
715aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
716aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    bool sendErrorReponse = true;
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(INITIALIZED);
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(CONFIGURED);
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
739c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
74503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
746aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
74703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
74803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
74903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
75003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
75103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
75203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
75303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
75403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
75503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
75603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
75703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
7695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
772575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
775c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
776c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
777749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang                                onError(omxError, 0);
778c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
779ec5f7cc4756d389505e761b9d803a1a3a46b64d7Lajos Molnar                            setState(UNINITIALIZED);
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sendErrorReponse = false;
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagStickyError;
788575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
789c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
790c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
791749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang                                onError(omxError, 0);
792c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
793ec5f7cc4756d389505e761b9d803a1a3a46b64d7Lajos Molnar                            setState(UNINITIALIZED);
7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (sendErrorReponse) {
799c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        PostReplyWithError(mReplyID, UNKNOWN_ERROR);
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
80492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
809717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
811717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags |= kFlagIsSoftwareCodec;
8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagIsSoftwareCodec;
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
8165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
817717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
8181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
8191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
8201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
8211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
8221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
8245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
82792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
8285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
8305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
8326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
8336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
834e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
835e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
836e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
8372606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
8395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
8405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
84292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
8437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
84492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
8457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
8467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
8477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
8487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
8497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
8507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
8517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
8526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
8537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
8547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
8557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
8567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
8577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
8587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
8597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
86092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
8617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
86292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
8637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
8647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
8657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
8667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
8677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
8687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
8697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
8707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
8717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
8727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
87392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
8745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
8757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
8765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
8845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
889eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
890eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
891eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
89292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
89392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
8945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
895eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
897eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
899eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
901eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
904ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
905ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                new ABuffer(info.mData->capacity());
906ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
907ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
9095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
920575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
92692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if ((mFlags & kFlagIsSoftwareCodec)
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            && mNativeWindow != NULL) {
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (!strncasecmp("video/", mime.c_str(), 6)) {
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            delete mSoftRenderer;
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer = NULL;
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t width, height;
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("width", &width));
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32("height", &height));
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9436539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            int32_t cropLeft, cropTop, cropRight, cropBottom;
9446539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            CHECK(msg->findRect("crop",
9456539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                                &cropLeft, &cropTop, &cropRight, &cropBottom));
9466539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            int32_t colorFormat;
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            CHECK(msg->findInt32(
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                        "color-format", &colorFormat));
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            sp<MetaData> meta = new MetaData;
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyWidth, width);
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyHeight, height);
9546539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                            meta->setRect(kKeyCropRect,
9556539f82d55d4457bc84ed23d57967346022c56dcMartin Storsjo                                cropLeft, cropTop, cropRight, cropBottom);
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            meta->setInt32(kKeyColorFormat, colorFormat);
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mSoftRenderer =
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                new SoftwareRenderer(mNativeWindow, meta);
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
964e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
965e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
966e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
967e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
968e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
969e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
970c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
971c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
972e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
973e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
974e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
975e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
97992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
983c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
984c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
985c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
9918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
9928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
9938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
9948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
9958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
9968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
9978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
9988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
9998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
10008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
10018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
10028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
10038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
10048ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
10058ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
10068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            mFlags |= kFlagStickyError;
1007575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1008575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
10098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
10108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
10118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
10128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
10138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1014c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1015c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onInputBufferAvailable();
1016c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1022575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1023575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
102892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1032c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1033c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1034c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10392d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
10402d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1047e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1048e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1049e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1050e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1051e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1052e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1053e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1054e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1055e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1056e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1057e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1058e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1059e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1060e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1061e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1062e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1063c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1064c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1065c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1066c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1067c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1068e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1069e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1070c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1071c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1072c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1078575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1079575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1081575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
108592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
109292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1094c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1095c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1096c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1097c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1098c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
1099c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
110592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, FLUSHING);
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(STARTED);
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mCodec->signalResume();
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1128c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
11400db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
11410db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1158c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1159c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
1160c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            uint32_t replyID;
1161c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1162c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1163c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1164c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
1165c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == STARTED) {
1166c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // callback can't be set after codec is started,
1167c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1168c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1169c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1170c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1171c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1172c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1173c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1174c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1175c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1176c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1177c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1178c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1179c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1180c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1181c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1182c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1183c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1184c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1185c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1186c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1187c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1188c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1189c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1196c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
12101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
12117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                status_t err = setNativeWindow(
12127541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    static_cast<NativeWindowWrapper *>(obj.get())
12137541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                        ->getSurfaceTextureClient());
12147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
12157541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1216c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
12177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
12181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
12191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
12207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                setNativeWindow(NULL);
12211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
12221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
12237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
12247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
12257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
12261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
12271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
12281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
12321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1238e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
12428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
12487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
12497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            uint32_t replyID;
12507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
12517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
12537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1254c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
12557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
12567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
12577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
12597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->initiateCreateInputSurface();
12607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
12617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
12627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != CONFIGURED) {
1269c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1281c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1282c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1283aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1284aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1285aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1286c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            uint32_t replyID;
1287c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1288c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1289c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            if (mState != INITIALIZED
1290c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    && mState != CONFIGURED && mState != STARTED) {
129103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // We may be in "UNINITIALIZED" state already without the
129203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
129303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
129403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
129503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
129603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1297aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // Similarly stopping a stopped MediaCodec should be benign.
1298c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
129903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                response->setInt32(
130003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                        "err",
1301aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mState == targetState ? OK : INVALID_OPERATION);
1302c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1303c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1304c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1305c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1306c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1307aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1308aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1309aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1310aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
1311aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1312aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1313aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1314aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1315c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1316aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1317aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1318aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1319aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1320c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1330c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1331c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1332c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1333c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1334c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1335c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
13366507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
13376507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1338c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
13396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
13406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
13416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1350c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueInputTimedOut, id());
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1379c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1392c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1398c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1407c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1408c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1409c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1410c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1411c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1412c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1421c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    new AMessage(kWhatDequeueOutputTimedOut, id());
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
14455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
14747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
14757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            uint32_t replyID;
14767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
14777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
14787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1479c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
14807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
14817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
14827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
14837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
14847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
14857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
14867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
14877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1494c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1510ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
15111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1512ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != STARTED || (mFlags & kFlagStickyError)) {
1525c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1537e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
1540e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
1541e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1542e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t replyID;
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1546e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
1547e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                 mState != STARTED && mState != FLUSHING)
1548972f2321583ef4094477271e0fc6a1d05a1a0eeaMartin Storsjo                    || (mFlags & kFlagStickyError)
1549e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
1550c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
1555e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1560496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
1561496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
1562496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
1563496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
1564496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
1565496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1566575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
1567575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
1568575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
1569575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
1570575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1571575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
1572575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
1573575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
1574575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1575717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
1576717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
1577717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            uint32_t replyID;
1578717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
1579717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1580717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
1581c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1582717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
1583717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
1584717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1585717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
1586717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
1587717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
1588717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
1589717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
1590717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1591a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
1592a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
1593a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            uint32_t replyID;
1594a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1595a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1596a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
1597a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
1598a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1599a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
1600a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1601c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
1602a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
1603a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
1604a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16108ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
16118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
16128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
16148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
16158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
16168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        if (!format->findBuffer(StringPrintf("csd-%u", i).c_str(), &csd)) {
16178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
16188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
16198ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
16218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
16228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
16238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1624a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
16258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
16268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
16288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
16298ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16307bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
16317bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
16328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
16348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
16358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
16378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
16388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
16408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
16418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
16428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
16448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
16468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, id());
16488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
16498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
16508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
16518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
16528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
16538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
16548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
16568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
16578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16585778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
16597541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
16647541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        setNativeWindow(NULL);
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1666671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
1671e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
1672e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
1673c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
1674575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1675575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
1676c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1679717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
1680671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
1681671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
1682671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
1683717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        mComponentName.clear();
1684aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1685aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
1686aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
1687aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
1688aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
1689717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
1690717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
16942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
16952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16985778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17035778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
17045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
17057bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
17187fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
17197fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17285778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1732609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
1733609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
17674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
17684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
17694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
17704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
17714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
17724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
17734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
17744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
17754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
17764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
17774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
17784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
17794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
17804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
17814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
17824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
17834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
17844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
17854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
17864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
17874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
17884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
17894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
17904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
17914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
17924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
17934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
17944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
17954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
17964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
17974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
17984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
17994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
18004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
18014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
18024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
18034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
18044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
18054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
18064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
18074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
18351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
18361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
1837ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1838ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
18395b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
18405b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
18415b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
1842fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
18431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
18441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
18451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
18461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
18471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                info->mEncryptedData->base() + offset,
18484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
18494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
18505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
18515b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
18521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1853fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
1854fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
1855ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
1856ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1857fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
1858ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
1859ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
18607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
18617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
18627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
18637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
18647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
18652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
18695b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mState != STARTED) {
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
18977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
18987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
18997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
19007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
19017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
190279ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1905fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
1906fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (msg->findInt64("timestampNs", &timestampNs)) {
1907fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            info->mNotify->setInt64("timestampNs", timestampNs);
1908fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        } else {
1909fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
1910fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
1911fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
1912fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
1913fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
1914fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
191547aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
1916fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
1917fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
1918fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
1919fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
1920fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
1923fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                    info->mData->data(), info->mData->size(), timestampNs, NULL);
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
19477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
19487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
19497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mFormat = portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
19507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
195103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
195203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
195303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
195403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
195503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
195603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
195703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
195803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
195903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
196003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
196103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
196203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
19637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19687541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow(
19691a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &surfaceTextureClient) {
19707541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
19717541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
19727541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (mNativeWindow != NULL) {
19737541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
19747541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
19757541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
19767541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
19777541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
19787541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
19797541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
19807541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
19817541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow.clear();
19827541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
19837541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
19847541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (surfaceTextureClient != NULL) {
19857541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
19867541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
19877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
19887541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
19897541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
19907541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
19917541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
19927541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
19937541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
19947541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
19957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow = surfaceTextureClient;
19967541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
19977541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
19987541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
19997541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
20007541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2001c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2002c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2003c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2004c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2005c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2006c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2007c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2008c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2009c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2010c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2011c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2012c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2013c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2014c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2015c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2016c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2017c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2018c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2019c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2020c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2021c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2022c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2023c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2024c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2025c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2026c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2027c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2028c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2029c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2030c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2031c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2032c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2033c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2034c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2035c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2036c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2037c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2038c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2039c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2040c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2041c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2042c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2043c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2044c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2045c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2046c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2047749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2048c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2049c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2050c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2051c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2052749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2053749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2054749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2055749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2056749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2057c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2058c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2059c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2060c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2061c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2062c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2063c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2064c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2065c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2066c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2067c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2068c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2069c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2070c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2071c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2072575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2073575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2074575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2075575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2076575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2077575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if ((mFlags & (kFlagStickyError
2078575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2079575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputFormatChanged))
2080575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2081575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2082575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2083575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2084575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2085575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2086575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2087a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
2088a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> msg = new AMessage(kWhatSetParameters, id());
2089a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2090a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2091a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2092a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2093a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2094a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2095a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2096a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2097a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2098a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2099a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2100a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2102e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2103e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2106e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2109e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2110e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2111e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2112e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2113e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2114e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2115e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2116e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2117e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2118e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2119e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2120e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2121e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2122e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2123e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2124e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2125e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    StringPrintf("csd-%u", csdIndex).c_str(), csd);
2126e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2127e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2128e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2129e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2130e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2131e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2132e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2133e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2134e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2135e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2136e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2137e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2138e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2139e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2140e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2141e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
21422606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
21432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
21442606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        AString mime;
21452606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        CHECK(mOutputFormat != NULL &&
21462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                mOutputFormat->findString("mime", &mime));
21472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mIsVideo = mime.startsWithIgnoreCase("video/");
21492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
21512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
21532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
21542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
21552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
21562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
21572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21582606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
21592606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
21602606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
21612606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
21632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
21642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
21652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
21662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
21672606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
21692606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
21702606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
21712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2173