MediaCodec.cpp revision d7ed649cfeff62680b8edb4cb86ce239116d8c8b
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>
25c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h>
262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h>
27c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/MemoryDealer.h>
281a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
29ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
315778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
335b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
34ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
372606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
386f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
39e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
405778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
41744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h>
425778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
435778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h>
442606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
452606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
47e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
485778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    BatteryNotifier();
52d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    virtual ~BatteryNotifier();
532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartVideo();
552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopVideo();
562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartAudio();
572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopAudio();
58d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    void onBatteryStatServiceDied();
592606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
602606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate:
61d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    struct DeathNotifier : public IBinder::DeathRecipient {
62d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        DeathNotifier() {}
63d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        virtual void binderDied(const wp<IBinder>& /*who*/) {
64d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            BatteryNotifier::getInstance().onBatteryStatServiceDied();
65d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
66d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    };
67d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
68d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex mLock;
692606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mVideoRefCount;
702606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mAudioRefCount;
712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    sp<IBatteryStats> mBatteryStatService;
72d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<DeathNotifier> mDeathNotifier;
73d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
74d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> getBatteryService_l();
75d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
76d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier);
772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang};
782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
792606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
812606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() :
822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount(0),
832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount(0) {
84d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
85d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
86d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() {
87d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mBatteryStatService != NULL) {
88d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        return mBatteryStatService;
89d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
90d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // get battery service from service manager
912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    const sp<IServiceManager> sm(defaultServiceManager());
922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (sm != NULL) {
932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        const String16 name("batterystats");
94d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mBatteryStatService =
95d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                interface_cast<IBatteryStats>(sm->getService(name));
962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mBatteryStatService == NULL) {
972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            ALOGE("batterystats service unavailable!");
98d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            return NULL;
99d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
100d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mDeathNotifier = new DeathNotifier();
101d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (IInterface::asBinder(mBatteryStatService)->
102d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                linkToDeath(mDeathNotifier) != OK) {
103d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService.clear();
104d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mDeathNotifier.clear();
105d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            return NULL;
1062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
107d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        // notify start now if media already started
108d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mVideoRefCount > 0) {
109d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartVideo(AID_MEDIA);
110d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
111d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mAudioRefCount > 0) {
112d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartAudio(AID_MEDIA);
113d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
114d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
115d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    return mBatteryStatService;
116d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
117d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
118d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() {
119d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mDeathNotifier != NULL) {
120d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        IInterface::asBinder(mBatteryStatService)->
121d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                unlinkToDeath(mDeathNotifier);
1222606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1232606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() {
126d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
127d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
128d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
129d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartVideo(AID_MEDIA);
1302606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1312606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount++;
1322606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1332606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1342606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() {
135d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
1362606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0) {
1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
1392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1402606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1412606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount--;
142d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
143d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopVideo(AID_MEDIA);
1452606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() {
149d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
150d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
151d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
152d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartAudio(AID_MEDIA);
1532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount++;
1552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() {
158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
1592606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mAudioRefCount == 0) {
1602606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
1612606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
1622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount--;
165d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
166d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopAudio(AID_MEDIA);
1682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1692606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
171d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() {
172d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
173d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mBatteryStatService.clear();
174d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mDeathNotifier.clear();
175d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // Do not reset mVideoRefCount and mAudioRefCount here. The ref
176d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // counting is independent of the battery service availability.
177d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // We need this if battery service becomes available after media
178d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // started.
179d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
180d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1825778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
183251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
1845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
1855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
186251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
187251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
188251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
189251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
190251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1945778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
195251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *name, status_t *err) {
1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
198251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
199251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
200251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
201251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
202251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
2035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2055778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
2065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
2075778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
20892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
2097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
2105778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
211251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
2125778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
2132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
2142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
2155778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
2165778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
2175778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
2186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
2196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mHaveInputSurface(false) {
2205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2225778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
2235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
2245778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2265778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2275778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
2285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
2295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
2305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
2325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
2335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
242c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static
2433f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
244c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
245c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->setInt32("err", err);
246c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
247c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
248c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
249dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
250671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
251671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
252671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
253671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
254671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
2575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
2585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
259744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
260bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung    if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {
261744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new ACodec;
262744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else if (!nameIsType
263bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung            && !strncasecmp(name.c_str(), "android.filter.", 15)) {
264744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new MediaFilter;
265744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else {
266744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
267744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
268744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    bool needDedicatedLooper = false;
270dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        needDedicatedLooper = true;
2726f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
2736f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
2746f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
2756f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
2766f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
27760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
2786f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
2796f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
28060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
28160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
28260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
28360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
28460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
28560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    needDedicatedLooper = true;
28660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
2876f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
2886f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
2896f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (needDedicatedLooper) {
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
3135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
320c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
3211d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
322c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
323c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
324c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
325c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
326c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
327c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
3301a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &nativeWindow,
3311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
3331d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nativeWindow != NULL) {
3391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setObject(
3401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                "native-window",
3411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new NativeWindowWrapper(nativeWindow));
3421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
3431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
3441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
3451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
349f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    status_t err = PostAndAwaitResponse(msg, &response);
350f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
351f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    if (err != OK && err != INVALID_OPERATION) {
352f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang        // MediaCodec now set state to UNINITIALIZED upon any fatal error.
353f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang        // To maintain backward-compatibility, do a reset() to put codec
354f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang        // back into INITIALIZED state.
355f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang        // But don't reset if the err is INVALID_OPERATION, which means
356f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang        // the configure failure is due to wrong state.
357f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
358f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang        ALOGE("configure failed with err 0x%08x, resetting...", err);
359f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang        reset();
360f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
361f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
362f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
3667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
3671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
3687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
3707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
3717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
3727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
3737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
3747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
3757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
3767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
3777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
3787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
3797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
3807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
3817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
3827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
3837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
3847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
3855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
3861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
3931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
399c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
4001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
401c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
402c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
403c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
404c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
405c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
406671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
407671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
408671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
409671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
410671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
411671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
412671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
413671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
414671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
415671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
416671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
417671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
418671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
419671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
420671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
421671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
422671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
423671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
424671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
425251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
426671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
427671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
428671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
429671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
430671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
431671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
432671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
433671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
434671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
435671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
436dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
437671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
438671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
439671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
440671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
4465b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
4475b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
4485b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
4495b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
4505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
4515b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
4521d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
4585b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
4654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
4664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
4674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
4684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
4694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
4704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
4714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
4724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
4735b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
4745b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
4755b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
4765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
4775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
4785b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
4791d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
4804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
4814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
4824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
4834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
4844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
4854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
4864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
4874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
4884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
4895b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
4904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
4914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
4925b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
4935b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
4945b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
4954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
4964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
4981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
5085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
5135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
5145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
5155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
5191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
5381d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
5395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
5405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
5415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
546fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
5471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
548fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
549fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
550fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
551fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
552fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
553fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
554fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
555fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
5571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
5585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
5595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
5625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
5651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
5667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
5687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
5697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5715778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
5721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
585e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
5861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
587e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
588e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
589e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
590e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
591e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
592e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
593e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
594e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
595e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
596e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
597e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
598e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
599717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
6001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
601717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
602717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
603717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
604717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
605717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
606717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
607717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
608717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
609717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
610717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
611717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
612717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
6141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6225778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
6231d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
6245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6317bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
6327bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
6337bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
6347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
6357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
6367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
6377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
6387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
6397bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
6407bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
6417bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
6427bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
6437bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
6447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
6457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
6460e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
6470e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
6480e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
6490e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
6507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
6517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
6527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
6537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
6547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
6557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
6567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
6570e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
6587bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
6597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
6607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
6617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
6627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
6637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
6647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
6657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
6667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
6677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
6680837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            // by the time buffers array is initialized, crypto is set
6690837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            if (portIndex == kPortIndexInput && mCrypto != NULL) {
6700837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mEncryptedData;
6710837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            } else {
6720837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mData;
6730837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            }
6747bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
6757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
6767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
6777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
6787bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
6797bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
6805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
6811d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
687496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
6881d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
689496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
690496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
691496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
692496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
693575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
6941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
695575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
696575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
697575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
698575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
6995778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7015778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
7025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
703c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
7075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
711c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
7125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7193f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
7200e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
722c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
724251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
725251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
726251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7433f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7460e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
749251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
750251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        response->setInt32("err", getStickyError());
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
7695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7995778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
80792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
809251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
810251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
811251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8139e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
8149e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
815251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
816aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
81752dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
818aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
819aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
8205530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
8245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
8255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
8275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
8285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
8305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
831c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
832c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
838c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
839c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
8405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
8425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
844c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8495530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
85003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
851aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
85203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
85303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
85403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
85503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
85603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
85703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
85803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
85903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
8606e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
8616e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
8626e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
86303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
86403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
8665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
8695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
8709e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
8719e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
8729e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
8739e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
8749e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
8759e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
8765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8790e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
8825530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
884251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
885575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
888c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
889c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
890251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
891251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
892251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
893251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
894251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
895251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
896251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
897251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
898251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
899251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
900251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
901c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
9075530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
909251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
910575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
911c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
912251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
913251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
914251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
915251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
916c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
917251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
918251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
919251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
920251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
921251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
922251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
923251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
924251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
925251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
926251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
927251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
928c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9335530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
934251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
93992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
94352dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
945717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
947717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
9483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
9503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
953717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
9541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
9551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
9561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
9571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
9581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
96392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9676507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
9686507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
9696507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
972e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
9733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
9743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
9753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
9763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
9773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
9782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
98392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
9847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
98592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
9867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
9877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
9887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
9897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
9907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
9917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
9927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
9936507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
9947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
9957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
9967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
9977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
9987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
9997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
10007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
100192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
10027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
100392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
10047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
10057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
10067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
10077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
10087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
10097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
10107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
10117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
10127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
101492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
10167bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1030eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1031eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1032eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
103392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
103492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1036eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1038c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1039c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1040c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1041c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1042c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1043c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1044c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1045c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1046c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1047c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1048c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1049eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1051eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1053eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1056c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1057ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
1058c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                                new ABuffer(mem->pointer(), info.mData->capacity());
1059c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1060ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1061ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1074575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
108092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1084475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1085475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                            mNativeWindow != NULL &&
10863a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1090475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1091475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                            mSoftRenderer = new SoftwareRenderer(mNativeWindow);
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
1096e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1098e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1099e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1100e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1101e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1102c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1103c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1104e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1105e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1106e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
11082514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
11092514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
11102514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
11118140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
11128140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
11138140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
11148140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
11158140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
11168140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
11178140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
11182514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
11192514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
112392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1129c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
11358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
11368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
11378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
11388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
11398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
11408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
11418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
11428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
11438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
11448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
11458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
11468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
11478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
11488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
11498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1151575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1152575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
11538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
11548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
11558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
11568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
11578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1158c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
11596e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
11606e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                            onInputBufferAvailable();
11616e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1162c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1168575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1169575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
117492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1178c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1179c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1180c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11852d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
11862d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1193e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1194e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1195e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1196e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1197e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1198e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1199e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1200e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1201e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1202e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1203e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1204e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1205e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1206e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1207e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1208e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1209c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1210c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1211c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1212c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1213c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1214e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1215e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1216c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1217c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1218c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1224575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1225575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1227575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
123192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
123892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1240c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1241c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1242c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1243c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1244c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
12456e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1246c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
124752dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
125392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12555530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
12565530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
12575530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
12585530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
12595530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12610e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
12620e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
12630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
12640e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
12650e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
12660e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
12745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
12765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12803f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1284c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
12960db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
12970db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1314c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1315c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
13163f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1317c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1318c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1319c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1320c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
13210e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
13220e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1323c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1324c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1325c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1326c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1327c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1328c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1329c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1330c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1331c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1332c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1333c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1334c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1335c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1336c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1337c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1338c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1339c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1340c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1341c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1342c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1343c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1344c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1345c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
13483f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1352c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
13535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
13661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
13677541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                status_t err = setNativeWindow(
13687541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    static_cast<NativeWindowWrapper *>(obj.get())
13697541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                        ->getSurfaceTextureClient());
13707541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
13717541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1372c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
13737541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
13741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
13751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
13767541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                setNativeWindow(NULL);
13771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
13781bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
13797541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
13807541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
13817541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
13821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
13831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
13841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
13881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1394e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
13988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
14047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
14053f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
14067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
14077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
14087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
14097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1410c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
14117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
14127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
14137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
14147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
14157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->initiateCreateInputSurface();
14167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
14177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
14187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
14213f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14240e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1425d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
14260e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
14270e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1428d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
14290e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1430c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1442c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1443c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1444aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1445aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1446aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
14473f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1448c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1449c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
145033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
145133223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
14520e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
145333223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
145433223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
145533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
145652dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
145703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
145803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
145903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
146003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
146103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1462c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
14636e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
14646e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
14656e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
14666e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
14676e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1472aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1473aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1474aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1475aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
14766e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
14776e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
14786e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1479aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1480aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1481aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1482aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1484aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1485aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1486aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1487aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1488c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
14895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
14953f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1498c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1499c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1500c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1501c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1502c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1503c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
15046507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
15056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1506c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
15086507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
15096507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1518c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
15271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1547c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15563f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1559251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1560c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1562251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1563251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1564251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1578c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1579c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1580c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1581c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1582c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1583c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1592c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
16011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1621c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16303f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1633251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1636251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1637251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1638251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1643c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
16487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
16493f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
16517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1652251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1653c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
1655251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1656251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1657251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
16587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
16597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
16617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
16627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
16637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
16647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16673f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1670251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting() || (mFlags & kFlagIsAsync)) {
1671c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1673251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1674251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1675251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1690ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
16911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1692ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17013f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1704251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1705c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1707251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1708251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1709251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
17105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
17130e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1721e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
1724e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
1725e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1726e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
17273f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1730e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
17310e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
17320e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
1733e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
1734c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1736251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1737251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1738251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
1742e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1747496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
1748496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
1749496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
1750496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
1751496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
1752496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1753575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
1754575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
1755575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
1756575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
1757575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1758575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
1759575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
1760575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
1761575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1762717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
1763717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
17643f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1765717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
1766717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1767717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
1768c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1769717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
1770717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
1771717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1772717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
1773717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
1774717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
1775717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
1776717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
1777717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1778a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
1779a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
17803f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1781a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1782a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1783a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
1784a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
1785a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1786a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
1787a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
1788c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
1789a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
1790a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
1791a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17978ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
17988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
17998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
18018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
18028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
1803a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
18048ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
18058ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
18068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
18088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
18098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
18108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1811a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
18128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
18138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
18158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
18168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18177bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
18187bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
18198ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
18218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
18228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
18248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
18258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
18278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
18288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
18298ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
18318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
18338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
18358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
18368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
18378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
18388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
18398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
18408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
18418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
18438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
18448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18455778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
18467541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
18517541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        setNativeWindow(NULL);
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1853671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
1858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
1859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
1860c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
1861251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
1862575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
1863575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
1864c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1867717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
1868671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
1869671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
1870671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
1871aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
1872aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
1873aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
1874aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
1875717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
1876717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
18802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
18812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18845778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18895778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
18917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
19047fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
19057fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19145778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1918609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
1919609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1930475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
1931475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
19554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
19564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
19574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
19584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
19594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
19604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
19614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
19624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
19634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
19644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
19654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
19664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
19674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
19684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
19694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
19704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
19714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
19724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
19734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
19744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
19754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
19764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
19774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
19784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
19794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
19804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
19814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
19824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
19834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
19844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
19854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
19864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
19874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
19884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
19894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
19904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
19914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
19924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
19934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
19944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
19954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
20231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
20241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
2025ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2026ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20275b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
20285b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
20295b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2030fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
20311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
20321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
20331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
20341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
2035c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2036c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
20374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
20384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
20395b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
20405b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
20411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2042fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2043fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2044ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2045ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2046fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
2047ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2048ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
20497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
20507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
20517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
20527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
20537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
20542d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20575b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
20585b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20710e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20857bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
20867bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
20877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
20887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
20897bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
20907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
209179ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2094fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
2095fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (msg->findInt64("timestampNs", &timestampNs)) {
2096fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            info->mNotify->setInt64("timestampNs", timestampNs);
2097fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        } else {
2098fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
2099fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
2100fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
2101fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
2102fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
2103fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
210447aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
2105fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
2106fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
2107fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
2108fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2109fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
2112475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
2113475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    timestampNs, NULL, info->mFormat);
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
21377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
21387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
21397bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
214003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
214103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
214203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
214303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
214403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
214503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
214603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
214703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
214803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
214903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
215003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
215103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
21527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21577541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow(
21581a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &surfaceTextureClient) {
21597541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
21607541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
21617541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (mNativeWindow != NULL) {
21627541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
21637541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
21647541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
21657541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
21667541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
21677541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
21687541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
21697541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
21707541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow.clear();
21717541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
21727541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
21737541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (surfaceTextureClient != NULL) {
21747541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
21757541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
21767541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
21777541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
21787541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
21797541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
21807541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
21817541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
21827541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
21837541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
21847541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow = surfaceTextureClient;
21857541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
21867541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
21877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
21887541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
21897541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2190c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2191c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2192c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2193c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2194c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2195c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2196c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2197c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2198c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2199c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2200c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2201c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2202c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2203c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2204c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2205c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2206c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2207c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2208c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2209c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2210c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2211c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2212c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2213c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2214c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2215c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2216c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2217c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2218c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2219c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2220c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2221c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2222c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2223c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2224c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2225c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2226c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2227c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2228c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2229c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2230c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2231c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2232c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2233c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2234c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2235c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2236749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2237c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2238c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2239c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2240c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2241749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2242749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2243749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2244749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2245749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2246c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2247c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2248c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2249c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2250c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2251c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2252c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2253c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2254c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2255c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2256c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2257c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2258c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2259c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2260c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2261575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2262575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2263575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2264575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2265575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2266e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2267e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2268575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2269e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2270e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2271e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2272575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2273575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2274e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2275e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2276e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2277e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2278e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2279e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2280e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2281e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2282e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2283e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2284575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2285575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2286575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2287575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2288575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2289a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
22901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2291a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2292a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2293a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2294a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2295a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2296a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2297a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2298a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2299a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2300a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2301a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2302a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2303e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2304e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2305e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2306e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2307e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2308e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2309e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2310e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2311e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2312e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2313e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2314e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2315e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2316e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2317e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2318e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2319e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2322e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2323e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2325e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2326e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2327a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2328e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2329e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2330e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2331e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2332e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2333e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2334e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2335e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2336e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2337e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2338e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2339e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2340e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2343e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
23442606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
23452606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
23462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        AString mime;
23472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        CHECK(mOutputFormat != NULL &&
23482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                mOutputFormat->findString("mime", &mime));
23492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
23502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mIsVideo = mime.startsWithIgnoreCase("video/");
23512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
23522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
23532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
23542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
23552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
23562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
23572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
23582606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
23592606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
23602606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
23612606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
23622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
23632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
23642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
23652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
23662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
23672606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
23682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
23692606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
23702606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
23712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
23722606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
23732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2375