MediaCodec.cpp revision 48a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5
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>
2667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <binder/IPCThreadState.h>
272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h>
28c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/MemoryDealer.h>
291a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
30ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
3167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h>
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
355b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
406f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
41e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
425778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
43744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h>
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h>
462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
49e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
505778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic inline int getCallingPid() {
5367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return IPCThreadState::self()->getCallingPid();
5467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
5567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic int64_t getId(sp<IResourceManagerClient> client) {
5767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (int64_t) client.get();
5867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
5967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) {
6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (err == OMX_ErrorInsufficientResources);
6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2;
6567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient {
6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool reclaimResource() {
7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (codec == NULL) {
7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // codec is already gone.
7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            return true;
7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        status_t err = codec->release();
7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK) {
7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
7967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (err == OK);
8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
828f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    virtual String8 getName() {
838f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        String8 ret;
848f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
858f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec == NULL) {
868f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            // codec is already gone.
878f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            return ret;
888f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
898f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu
908f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        AString name;
918f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec->getName(&name) == OK) {
928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            ret.setTo(name.c_str());
938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        return ret;
958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    }
9667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
9767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected:
9867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual ~ResourceManagerClient() {}
9967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate:
10167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    wp<MediaCodec> mMediaCodec;
10267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
10467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu};
10567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
1062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
1072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    BatteryNotifier();
108d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    virtual ~BatteryNotifier();
1092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartVideo();
1112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopVideo();
1122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartAudio();
1132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopAudio();
114d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    void onBatteryStatServiceDied();
1152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate:
117d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    struct DeathNotifier : public IBinder::DeathRecipient {
118d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        DeathNotifier() {}
119d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        virtual void binderDied(const wp<IBinder>& /*who*/) {
120d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            BatteryNotifier::getInstance().onBatteryStatServiceDied();
121d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
122d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    };
123d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
124d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex mLock;
1252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mVideoRefCount;
1262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mAudioRefCount;
1272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    sp<IBatteryStats> mBatteryStatService;
128d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<DeathNotifier> mDeathNotifier;
129d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
130d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> getBatteryService_l();
131d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
132d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier);
1332606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang};
1342606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1352606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
1362606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() :
1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount(0),
1392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount(0) {
140d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
141d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
142d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() {
143d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mBatteryStatService != NULL) {
144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        return mBatteryStatService;
145d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
146d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // get battery service from service manager
1472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    const sp<IServiceManager> sm(defaultServiceManager());
1482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (sm != NULL) {
1492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        const String16 name("batterystats");
150d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mBatteryStatService =
151d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                interface_cast<IBatteryStats>(sm->getService(name));
1522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mBatteryStatService == NULL) {
1532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            ALOGE("batterystats service unavailable!");
154d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            return NULL;
155d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
156d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mDeathNotifier = new DeathNotifier();
15745c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang        IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier);
158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        // notify start now if media already started
159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mVideoRefCount > 0) {
160d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartVideo(AID_MEDIA);
161d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
162d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mAudioRefCount > 0) {
163d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartAudio(AID_MEDIA);
164d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
165d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
166d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    return mBatteryStatService;
167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() {
170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mDeathNotifier != NULL) {
171d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        IInterface::asBinder(mBatteryStatService)->
172d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                unlinkToDeath(mDeathNotifier);
1732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1742606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1752606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1762606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() {
177d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
178d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
179d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
180d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartVideo(AID_MEDIA);
1812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount++;
1832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() {
186d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0) {
1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
1892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
1902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
192d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
19345c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang
19445c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang    mVideoRefCount--;
195d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
196d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopVideo(AID_MEDIA);
1972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
2002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() {
201d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
202d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
203d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
204d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartAudio(AID_MEDIA);
2052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount++;
2072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
2082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
2092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() {
210d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
2112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mAudioRefCount == 0) {
2122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
2132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
2142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
216d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
21745c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang
21845c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang    mAudioRefCount--;
219d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
220d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopAudio(AID_MEDIA);
2212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2222606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
223d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
224d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() {
225d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
226d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mBatteryStatService.clear();
227d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mDeathNotifier.clear();
228d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // Do not reset mVideoRefCount and mAudioRefCount here. The ref
229d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // counting is independent of the battery service availability.
230d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // We need this if battery service becomes available after media
231d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // started.
232d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
233d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
23467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() {
23567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
23667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
23767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
251e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu    IInterface::asBinder(mService)->linkToDeath(this);
25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
25467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
25567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int pid,
26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const sp<IResourceManagerClient> client,
26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->addResource(pid, clientId, client, resources);
27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->removeResource(clientId);
27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
28167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int callingPid, const Vector<MediaResource> &resources) {
28267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
28367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
28467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
28567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return mService->reclaimResource(callingPid, resources);
28767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
28867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2905778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
291251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
294251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
295251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
296251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
297251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3025778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
303251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *name, status_t *err) {
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
306251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
307251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
308251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
309251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3135778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
31692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
3177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
319251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
321ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
322ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerService(new ResourceManagerServiceProxy()),
3232606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
3242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
32567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
32667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
3306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
3313d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
3323d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3355778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
33767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
356c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static
3573f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
358c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
359c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->setInt32("err", err);
360c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
361c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
362c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
363dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
36467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
36567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
366671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
367671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
368671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
369671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
370671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
375744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
376bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung    if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {
377744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new ACodec;
378744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else if (!nameIsType
379bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung            && !strncasecmp(name.c_str(), "android.filter.", 15)) {
380744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new MediaFilter;
381744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else {
382744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
383744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
384744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
38567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
386dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
38767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
3886f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
3896f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
3906f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
39167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
3926f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
3936f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
39460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
39548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        if (mcl == NULL) {
39648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            mCodec = NULL;  // remove the codec.
39748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            return NO_INIT; // if called from Java should raise IOException
39848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        }
3996f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
4006f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
40160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
40260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
40360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
40460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
40560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
40667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
40760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
4086f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
4096f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
4106f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
41467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4301d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
43967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
44067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
441c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
442c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
44467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
44567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
44667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
44767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
44867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
44967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
45067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
45167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
45267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
45367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
45467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
45567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
45667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
45767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
4611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
4701a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &nativeWindow,
4711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
4731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
47667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
47767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
47867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
47967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nativeWindow != NULL) {
4841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setObject(
4851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                "native-window",
4861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new NativeWindowWrapper(nativeWindow));
4871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
4881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
4891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
4901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
49467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
495f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
49667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
49767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
49867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
49967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
500c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
501c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
50267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
50367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
50467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
50967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
51067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
51167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
512f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
51367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
51467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
51567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
51667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
51767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
51867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
51967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
52067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
52167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
52367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
52567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
52667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
52767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
528f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
529f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
5337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
5341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
5357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
5377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
5387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
5397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
5407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
5417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
5427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
5437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
5447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
5457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
5467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
5477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
5487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
5497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
5507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() {
55367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (!mIsVideo) {
55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return 0;
55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
55667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    uint64_t size = 0;
55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
55967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (size_t i = 0; i < portNum; ++i) {
56067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // TODO: this is just an estimation, we should get the real buffer size from ACodec.
56167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
56267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return size;
56467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
566c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wuvoid MediaCodec::addResource(const String8 &type, const String8 &subtype, uint64_t value) {
56767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
568c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(type, subtype, value));
56967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->addResource(
57067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources);
57167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
57267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
5741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
57867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
580c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
581c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
58467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
58567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
58667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
58767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
58867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
58967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
59067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
59167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Recover codec from previous error before retry start.
59267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = reset();
59367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to reset codec");
59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
59767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            sp<AMessage> response;
59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = PostAndAwaitResponse(mConfigureMsg, &response);
59967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
60067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to configure codec");
60167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
60267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
60767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
60867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
60967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
61067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
61167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
6151d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
6221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
628671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
629671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
630671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
631671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
632671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
633671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
634671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
635671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
636671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
637671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
638671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
639671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
640671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
641671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
642671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
643671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
644671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
645671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
646671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
647251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
648671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
649671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
650671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
651671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
652671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
653671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
654671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
655671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
656671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
657671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
658dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
659671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
660671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
661671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
662671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
6655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
6665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
6675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
6685b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6695b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6705b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6715b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6725b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
6735b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
6765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
6805b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
6874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
6884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
6894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
6904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
6914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
6924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
6934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
6944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
6955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6975b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6985b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
7005b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
7024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
7034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
7044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
7054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
7064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
7074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
7084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
7094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
7104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
7115b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
7124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
7145b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
7155b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7165b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
7174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
7184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
7201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
7411d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
7601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
768fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
7691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
770fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
771fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
772fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
773fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
774fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
775fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
776fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
777fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
7791d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
7871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
7887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
7907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
7917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
7927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
7941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
8081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
809e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
810e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
816e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
817e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
818e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
819e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
820e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
821717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
8221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
823717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
824717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
825717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
826717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
827717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
828717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
829717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
830717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
831717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
832717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
833717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
834717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
835e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const {
836e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
837e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("portIndex", kPortIndexInput);
838e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setPointer("buffers", buffers);
839e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("widevine", true);
840e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
841e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> response;
842e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    return PostAndAwaitResponse(msg, &response);
843e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar}
844e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
8461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
8551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
8647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
8667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
8697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
8707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
8747bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
8767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8780e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
8790e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
8800e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
8810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
8827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
8837bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
8847bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
8857bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
8867bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
8887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
8890e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
8907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
8917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
8927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
8947bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
8967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
8977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
8987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
8997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
9000837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            // by the time buffers array is initialized, crypto is set
9010837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            if (portIndex == kPortIndexInput && mCrypto != NULL) {
9020837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mEncryptedData;
9030837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            } else {
9040837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mData;
9050837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            }
9067bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
9077bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
9087bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
9097bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
9107bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
9131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
919496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
9201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
921496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
922496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
923496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
924496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
925575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
9261d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
927575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
928575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
929575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
930575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9335778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
935c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
943c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9513f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9520e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
954c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
956251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
957251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
958251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9780e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
981251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
982251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        response->setInt32("err", getStickyError());
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10315778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
103992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1041251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1042251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1043251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10459e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
10469e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1047251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1048aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
104952dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1050aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1051aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
10525530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1063c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1064c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1070c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1071c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
1076c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10815530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
108203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
1083aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
108403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
108503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
108603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
108703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
108803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
108903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
109003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
109103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
10926e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
10936e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
10946e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
109503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
109603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11029e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
11039e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
11049e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
11059e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
11069e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
11079e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11110e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11145530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1117575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1120c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1121c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1132251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1133c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11395530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1142575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1143c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1144251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1145251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1146251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1147251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1148c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1149251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1152251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1153251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1154251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1155251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1156251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1157251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1158251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1159251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1160c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11655530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1166251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
117192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
117552dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1177717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1179717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
11803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
11823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
118567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    String8 resourceType;
1186717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
11871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
118867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceSecureCodec);
11891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
11901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
119167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceNonSecureCodec);
11921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
1193c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu
1194c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
1195c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    addResource(resourceType, String8(subtype), 1);
11961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
120192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
12066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
12076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1208e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1209e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1210e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
12123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
12133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
12143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
12162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
122192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
12227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
122392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
12247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
12257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
12267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
12277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
12287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
12297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
12307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
12316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
12327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
12337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
123992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
12407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
124192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
12427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
12437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
12447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
12457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
125292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1268eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1269eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
127192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
127292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1276c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1277c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1278c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1279c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1280c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1281c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1282c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1283c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1284c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1285c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1286c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1287eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1289eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1291eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1294c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1295ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
1296c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                                new ABuffer(mem->pointer(), info.mData->capacity());
1297c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
130867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            if (mIsVideo) {
1309c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                String8 subtype;
1310c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                addResource(
1311c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        String8(kResourceGraphicMemory),
1312c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        subtype,
1313c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        getGraphicBufferSize());
131467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            }
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1319575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
132592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1329475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1330475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                            mNativeWindow != NULL &&
13313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1335475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1336475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                            mSoftRenderer = new SoftwareRenderer(mNativeWindow);
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
1341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1343e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1344e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1346e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1347c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1348c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1349e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1350e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1351e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1352e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
13532514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13542514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
13552514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
13568140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
13578140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
13588140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
13598140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
13608140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
13618140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
13628140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
13632514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
13642514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
136892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1372c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1373c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
13808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
13818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
13828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
13848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
13858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
13868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
13878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
13888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
13908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
13928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
13938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
13948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1395251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1396575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1397575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
13988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
13998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
14008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
14018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
14028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1403c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
14046e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
14053d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
14063d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
14073d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
14083d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
14093d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
14106e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1411c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1417575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1418575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
142392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14342d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
14352d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1449e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1455e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1456e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1457e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1459c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1463e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1464e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1473575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1474575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1476575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
148092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
148792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1489c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1490c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1491c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1492c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
14946e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
149652dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
149867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
149967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
150492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15065530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
15075530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
15085530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
15095530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
15105530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15120e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
15130e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
15140e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
15150e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
15160e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
15170e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15313f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1535c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
15470db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
15480db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1565c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1566c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
15673f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1568c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1570c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1571c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
15720e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
15730e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1574c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1575c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1576c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1577c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1578c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1579c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1580c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1581c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1582c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1583c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1584c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1585c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1586c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1587c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1588c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1589c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1590c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1591c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1592c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1593c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1594c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1595c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1596c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15993f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1603c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
16171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                status_t err = setNativeWindow(
16197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    static_cast<NativeWindowWrapper *>(obj.get())
16207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                        ->getSurfaceTextureClient());
16217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1623c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
16247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
16251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
16261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
16277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                setNativeWindow(NULL);
16281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
16291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16307541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
16317541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
16327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
16341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
16351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
16391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
16498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
16557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
16563f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
16587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
16607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1661c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
16637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
16647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
16667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->initiateCreateInputSurface();
16677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
16687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
16697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16723f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16750e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1676d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
16773d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
16783d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
16793d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
16803d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
16810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
16820e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1683d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
16840e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1685c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1697c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1698c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1699aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1700aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1701aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
17023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
170533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
170633223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
17070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
170833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
170933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
171033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
171152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
171203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
171303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
171403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
171503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
171603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
17186e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
17196e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
17206e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
17216e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
17226e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1727aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1728aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1729aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1730aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
17316e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
17326e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
17336e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1734aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1735aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1736aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1737aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1738c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1739aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1740aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1741aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1742aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17503f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1753c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1754c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1755c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1756c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1757c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1758c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
17596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
17606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1761c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
17636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
17646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1773c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
17821d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1802c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18113f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1814251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1815c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1817251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1818251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1819251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1824c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18303f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1833c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1834c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1835c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1836c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1837c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1838c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1847c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
18561d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1876c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18853f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1888251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1889c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1891251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1892251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1893251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1898c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
19037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
19043f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
19067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1907251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1908c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
1910251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1911251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1912251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
19147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
19157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
19167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
19177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
19187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
19197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19223f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1924e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // Unfortunately widevine legacy source requires knowing all of the
1925e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // codec input buffers, so we have to provide them even in async mode.
1926e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            int32_t widevine = 0;
1927e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            msg->findInt32("widevine", &widevine);
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1929e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
1930c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1932251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1933251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1934251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1949ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
19501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1951ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19603f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1963251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1964c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1966251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1967251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1968251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
19720e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1980e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
1983e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
1984e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1985e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
19863f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1989e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
19900e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
19910e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
1992e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
1993c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1995251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1996251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1997251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
2001e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2006496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
2007496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
2008496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
2009496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
2010496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
2011496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2012575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
2013575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
2014575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
2015575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
2016575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2017575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
2018575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
2019575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
2020575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2021717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2022717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
20233f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2024717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2025717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2026717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2027c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2028717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2029717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2030717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2031717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2032717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2033717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2034717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2035717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2036717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2037a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2038a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
20393f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2040a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2041a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2042a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2043a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2044a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2045a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2046a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2047c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2048a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2049a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2050a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20568ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
20578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
20588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
20608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
20618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2062a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
20638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
20648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
20658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
20678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
20688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
20698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2070a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
20718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
20728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
20748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
20758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
20777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
20788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
20808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
20818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
20838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
20848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
20868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
20878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
20888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
20908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
20928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
20948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
20958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
20968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
20978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
20988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
20998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
21008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
21028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
21038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21045778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
21057541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
21107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        setNativeWindow(NULL);
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2112671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2117e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2118e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
2119c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2121575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2122575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2123c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2126717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2127671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2128671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2129671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2130aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2131aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2132aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2133aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2134717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2135717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
21392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21402606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21435778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21485778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
21507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
21637fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
21647fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21735778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2177609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
2178609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2189475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
2190475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
22144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
22154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
22164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
22174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
22184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
22204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
22214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
22224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
22244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
22254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
22264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
22274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
22294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
22304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
22314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
22324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
22344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
22354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
22364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
22394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
22404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
22414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
22424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
22444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
22454b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22464b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
22474b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
22494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
22504b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
22514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
22524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
22544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
22821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
22831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
2284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2285ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
22865b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
22875b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
22885b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2289fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
22901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
22911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
22921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
22931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
2294c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2295c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
22964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
22974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
22985b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
22995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
23001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2301fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2302fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2303ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2304ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2305fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
2306ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2307ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
23087bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
23097bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23107bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
23127bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
23132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23165b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
23175b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23300e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
23457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
23487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
23497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
235079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2353fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
2354fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (msg->findInt64("timestampNs", &timestampNs)) {
2355fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            info->mNotify->setInt64("timestampNs", timestampNs);
2356fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        } else {
2357fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
2358fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
2359fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
2360fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
2361fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
2362fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
236347aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
2364fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
2365fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
2366fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
2367fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2368fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
2371475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
2372475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    timestampNs, NULL, info->mFormat);
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
23967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
239903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
240003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
240103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
240203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
240303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
240403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
240503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
240603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
240703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
240803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
240903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
241003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
24117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow(
24171a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &surfaceTextureClient) {
24187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
24197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (mNativeWindow != NULL) {
24217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
24227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
24237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
24257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
24267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
24277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
24287541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24297541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow.clear();
24307541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
24317541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (surfaceTextureClient != NULL) {
24337541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
24347541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
24357541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24367541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
24377541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
24387541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
24397541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24407541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
24417541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
24427541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24437541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow = surfaceTextureClient;
24447541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
24457541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24467541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
24477541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
24487541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2459c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2468c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2470c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2471c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2472c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2473c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2474c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2475c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2476c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2478c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2479c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2480c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2481c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2482c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2483c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2484c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2485c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2486c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2487c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2488c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2489c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2490c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2491c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2492c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2493c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2494c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2495749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2498c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2499c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2500749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2501749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2502749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2503749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2504749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2505c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2506c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2507c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2508c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2509c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2510c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2511c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2512c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2513c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2514c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2515c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2516c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2517c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2518c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2519c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2520575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2521575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2522575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2523575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2524575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2525e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2526e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2527575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2528e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2529e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2530e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2531575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2532575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2533e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2534e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2535e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2536e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2537e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2538e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2539e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2540e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2541e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2542e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2543575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2544575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2545575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2546575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2547575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2548a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
25491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2550a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2551a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2552a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2553a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2554a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2555a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2556a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2557a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2558a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2559a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2560a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2561a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2586a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
26032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
26042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
26052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
26062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
26082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
26092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
26102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
26112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
26122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
26142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
26152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
26162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26172606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
26182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
26192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
26202606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
26212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
26222606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26232606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
26242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
26252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
26262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2628