MediaCodec.cpp revision 8f9dd872366f54b6260506c75c3d0cc3f9f73f81
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    }
818f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua 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();
157d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (IInterface::asBinder(mBatteryStatService)->
158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                linkToDeath(mDeathNotifier) != OK) {
159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService.clear();
160d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mDeathNotifier.clear();
161d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            return NULL;
1622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
163d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        // notify start now if media already started
164d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mVideoRefCount > 0) {
165d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartVideo(AID_MEDIA);
166d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mAudioRefCount > 0) {
168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartAudio(AID_MEDIA);
169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
171d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    return mBatteryStatService;
172d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
173d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
174d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() {
175d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mDeathNotifier != NULL) {
176d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        IInterface::asBinder(mBatteryStatService)->
177d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                unlinkToDeath(mDeathNotifier);
1782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() {
182d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
183d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
184d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
185d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartVideo(AID_MEDIA);
1862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount++;
1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() {
191d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
1922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0) {
1932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
1942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
1952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount--;
198d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
199d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
200d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopVideo(AID_MEDIA);
2012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
2032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
2042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() {
205d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
206d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
207d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
208d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartAudio(AID_MEDIA);
2092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount++;
2112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
2122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
2132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() {
214d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
2152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mAudioRefCount == 0) {
2162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
2172606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
2182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
2202606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount--;
221d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
222d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
223d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopAudio(AID_MEDIA);
2242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
226d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
227d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() {
228d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
229d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mBatteryStatService.clear();
230d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mDeathNotifier.clear();
231d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // Do not reset mVideoRefCount and mAudioRefCount here. The ref
232d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // counting is independent of the battery service availability.
233d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // We need this if battery service becomes available after media
234d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // started.
235d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
236d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
23767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() {
23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
254e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu    IInterface::asBinder(mService)->linkToDeath(this);
25567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int pid,
26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const sp<IResourceManagerClient> client,
26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->addResource(pid, clientId, client, resources);
27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->removeResource(clientId);
28167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
28267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
28367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
28467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int callingPid, const Vector<MediaResource> &resources) {
28567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
28767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
28867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
28967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return mService->reclaimResource(callingPid, resources);
29067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
29167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2935778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
294251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
297251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
299251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
300251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
301251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3055778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
306251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *name, status_t *err) {
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
309251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
311251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
312251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
313251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3165778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
31992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
3207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
322251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
324ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
325ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerService(new ResourceManagerServiceProxy()),
3262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
3272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
32867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
32967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
3336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
3343d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
3353d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3385778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
34067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
359c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static
3603f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
361c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
362c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->setInt32("err", err);
363c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
364c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
365c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
366dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
36767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
36867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
369671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
370671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
371671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
372671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
373671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
378744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
379bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung    if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {
380744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new ACodec;
381744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else if (!nameIsType
382bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung            && !strncasecmp(name.c_str(), "android.filter.", 15)) {
383744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new MediaFilter;
384744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else {
385744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
386744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
387744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
38867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
389dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
39067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
3916f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
3926f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
3936f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
39467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
3956f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
3966f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
39760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
3986f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
3996f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
40060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
40160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
40260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
40360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
40460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
40567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
40660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
4076f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
4086f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
4096f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
41367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4291d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
43867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
43967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
44067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(type), 1));
44167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
44267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
44467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
44567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
44667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
44767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
44867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
44967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
45067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
45167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
45267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
45367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
45467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
45567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
4591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
4681a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &nativeWindow,
4691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
4711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
47367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
47467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
47567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
47667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
47767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nativeWindow != NULL) {
4821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setObject(
4831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                "native-window",
4841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new NativeWindowWrapper(nativeWindow));
4851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    }
4861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
4871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
4881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
49267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
493f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
49467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
49567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
49667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
49767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
49867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(type), 1));
49967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
50067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
50167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
50267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
50367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
50467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
509f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
51067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
51167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
51267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
51367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
51467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
51567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
51667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
51767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
51867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
51967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
52067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
52167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
52367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
525f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
526f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
5307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
5311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
5327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
5347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
5357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
5367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
5377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
5387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
5397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
5407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
5417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
5427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
5437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
5447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
5457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
5467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
5477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
54967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() {
55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (!mIsVideo) {
55167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return 0;
55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
55367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    uint64_t size = 0;
55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
55667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (size_t i = 0; i < portNum; ++i) {
55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // TODO: this is just an estimation, we should get the real buffer size from ACodec.
55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
55967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
56067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return size;
56167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
56267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::addResource(const char *type, uint64_t value) {
56467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(type), value));
56667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->addResource(
56767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources);
56867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
56967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
5711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
57467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
57567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
57667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(type), 1));
57867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
58067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
58167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
58467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
58567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
58667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
58767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Recover codec from previous error before retry start.
58867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = reset();
58967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
59067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to reset codec");
59167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
59267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
59367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            sp<AMessage> response;
59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = PostAndAwaitResponse(mConfigureMsg, &response);
59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to configure codec");
59767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
59967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
60067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
60167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
60267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
60767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
6111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
6181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
624671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
625671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
626671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
627671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
628671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
629671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
630671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
631671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
632671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
633671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
634671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
635671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
636671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
637671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
638671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
639671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
640671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
641671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
642671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
643251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
644671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
645671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
646671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
647671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
648671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
649671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
650671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
651671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
652671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
653671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
654dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
655671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
656671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
657671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
658671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
6595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
6645b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6665b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6675b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6685b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
6695b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6701d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
6715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
6725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
6735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
6745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
6765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
6834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
6844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
6854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
6864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
6874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
6884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
6894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
6904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
6915b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6925b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6935b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6945b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
6965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
6984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
6994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
7004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
7014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
7024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
7034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
7044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
7054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
7064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
7075b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
7084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
7105b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
7115b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7125b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
7134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
7144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
7161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
7371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
7561d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
764fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
7651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
766fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
767fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
768fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
769fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
770fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
771fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
772fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
773fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
7751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
7831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
7847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
7867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
7877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
7887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
7901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
8041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
806e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
809e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
810e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
816e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
817717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
8181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
819717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
820717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
821717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
822717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
823717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
824717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
825717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
826717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
827717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
828717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
829717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
830717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
831e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const {
832e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
833e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("portIndex", kPortIndexInput);
834e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setPointer("buffers", buffers);
835e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("widevine", true);
836e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
837e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> response;
838e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    return PostAndAwaitResponse(msg, &response);
839e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar}
840e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
8415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
8421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
8511d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
8607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
8627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
8657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
8667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
8677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
8707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
8750e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
8760e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
8770e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
8787bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
8797bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
8807bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
8817bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
8827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8837bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
8847bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
8850e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
8867bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
8877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
8887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8897bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
8907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
8917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
8927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
8937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
8947bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
8960837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            // by the time buffers array is initialized, crypto is set
8970837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            if (portIndex == kPortIndexInput && mCrypto != NULL) {
8980837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mEncryptedData;
8990837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            } else {
9000837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mData;
9010837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            }
9027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
9037bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
9047bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
9057bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
9067bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9077bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
9091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
915496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
9161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
917496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
918496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
919496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
920496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
921575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
9221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
923575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
924575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
925575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
926575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9295778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
931c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
939c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9473f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9480e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
950c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
952251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
953251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
954251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9713f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
977251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
978251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        response->setInt32("err", getStickyError());
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10275778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
103592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1037251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1038251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1039251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10419e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
10429e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1043251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1044aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
104552dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1046aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1047aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
10485530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1059c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1060c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1066c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1067c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
1072c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10775530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
107803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
1079aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
108003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
108103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
108203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
108303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
108403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
108503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
108603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
108703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
10886e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
10896e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
10906e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
109103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
109203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10989e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
10999e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
11009e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
11019e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
11029e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
11039e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11105530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1113575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1116c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1117c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1129c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11355530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1137251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1138575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1139c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1140251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1142251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1143251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1144c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1145251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1146251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1147251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1148251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1149251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1152251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1153251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1154251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1155251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1156c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11615530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1162251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
116792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
117152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1173717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1175717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
11763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
11783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
118167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    String8 resourceType;
1182717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
11831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
118467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceSecureCodec);
11851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
11861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
118767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceNonSecureCodec);
11881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
118967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    addResource(resourceType, 1);
11901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
119592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
12006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
12016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1204e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
12063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
12073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
12083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
12102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
121592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
12167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
121792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
12187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
12197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
12207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
12217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
12227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
12237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
12247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
12256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
12267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
12277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
123392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
12347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
123592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
12367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
12377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
12387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
12397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
124692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1262eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1263eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1264eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
126592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
126692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1268eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1270c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1271c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1272c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1273c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1274c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1275c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1276c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1277c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1278c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1279c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1280c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1281eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1283eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1285eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1288c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1289ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
1290c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                                new ABuffer(mem->pointer(), info.mData->capacity());
1291c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1292ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
130267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            if (mIsVideo) {
130367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                                addResource(kResourceGraphicMemory, getGraphicBufferSize());
130467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            }
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1309575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
131592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1319475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1320475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                            mNativeWindow != NULL &&
13213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1325475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1326475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                            mSoftRenderer = new SoftwareRenderer(mNativeWindow);
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
1331e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1332e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1333e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1334e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1335e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1336e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1337c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1338c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1339e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1340e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
13432514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13442514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
13452514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
13468140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
13478140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
13488140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
13498140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
13508140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
13518140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
13528140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
13532514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
13542514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
135892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
13708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
13718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
13728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
13748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
13758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
13768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
13778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
13788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
13808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
13828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
13838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
13848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1385251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1386575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1387575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
13888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
13898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
13908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
13918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
13928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1393c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
13946e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
13953d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
13963d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
13973d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
13983d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
13993d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
14006e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1401c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1407575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1408575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
141392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1417c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1418c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14242d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
14252d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1448c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1463575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1464575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1466575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
147092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
147792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1482c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
14846e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1485c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
148652dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
148867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
148967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
149492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14965530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
14975530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
14985530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
14995530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
15005530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15020e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
15030e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
15040e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
15050e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
15060e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
15070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15213f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1525c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
15370db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
15380db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1555c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1556c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
15573f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1558c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1559c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1560c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1561c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
15620e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
15630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1564c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1565c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1566c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1567c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1568c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1570c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1571c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1572c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1573c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1574c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1575c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1576c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1577c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1578c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1579c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1580c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1581c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1582c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1583c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1584c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1585c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1586c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15893f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1593c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (!msg->findObject("native-window", &obj)) {
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                obj.clear();
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
16071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16087541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                status_t err = setNativeWindow(
16097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    static_cast<NativeWindowWrapper *>(obj.get())
16107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                        ->getSurfaceTextureClient());
16117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16127541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1613c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
16147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
16151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
16161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
16177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                setNativeWindow(NULL);
16181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
16191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
16217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
16227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
16241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
16251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
16291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
16398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
16457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
16463f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
16487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
16507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1651c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
16537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
16547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
16567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->initiateCreateInputSurface();
16577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
16587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
16597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16623f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16650e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1666d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
16673d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
16683d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
16693d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
16703d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
16710e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
16720e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1673d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
16740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1675c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1689aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1690aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1691aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
16923f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1693c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
169533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
169633223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
16970e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
169833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
169933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
170033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
170152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
170203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
170303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
170403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
170503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
170603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
17086e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
17096e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
17106e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
17116e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
17126e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1713c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1714c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1715c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1717aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1718aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1719aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1720aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
17216e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
17226e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
17236e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1724aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1725aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1726aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1727aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1729aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1730aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1731aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1732aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17403f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1743c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1744c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1745c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1746c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1747c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1748c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
17496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
17506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1751c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
17536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
17546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1763c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
17721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1792c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18013f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1804251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1805c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1807251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1808251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1809251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1814c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18203f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1823c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1824c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1825c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1826c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1827c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1828c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1837c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
18461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1866c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1878251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1879c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1881251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1882251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1883251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1888c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
18937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
18943f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
18967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1897251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1898c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
1900251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1901251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1902251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
19047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
19057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
19067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
19077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
19087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
19097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19123f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1914e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // Unfortunately widevine legacy source requires knowing all of the
1915e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // codec input buffers, so we have to provide them even in async mode.
1916e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            int32_t widevine = 0;
1917e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            msg->findInt32("widevine", &widevine);
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1919e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
1920c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1922251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1923251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1924251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1939ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
19401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1941ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19503f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1953251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1954c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1956251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1957251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1958251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
19620e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
1973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
1974e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
1975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
19763f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1979e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
19800e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
19810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
1982e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
1983c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1985251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1986251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1987251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
1991e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1996496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
1997496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
1998496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
1999496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
2000496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
2001496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2002575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
2003575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
2004575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
2005575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
2006575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2007575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
2008575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
2009575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
2010575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2011717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2012717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
20133f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2014717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2015717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2016717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2017c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2018717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2019717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2020717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2021717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2022717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2023717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2024717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2025717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2026717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2027a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2028a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
20293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2030a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2031a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2032a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2033a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2034a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2035a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2036a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2037c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2038a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2039a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2040a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20468ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
20478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
20488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
20508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
20518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2052a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
20538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
20548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
20558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
20578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
20588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
20598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2060a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
20618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
20628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
20648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
20658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
20677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
20688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
20708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
20718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
20738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
20748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
20768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
20778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
20788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
20808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
20828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
20848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
20858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
20868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
20878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
20888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
20898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
20908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
20928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
20938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
20945778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
20957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
21007541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        setNativeWindow(NULL);
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2102671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
2109c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2111575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2112575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2113c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2116717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2117671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2118671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2119671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2120aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2121aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2122aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2123aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2124717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2125717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
21292606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21302606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21335778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21385778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
21407bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
21537fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
21547fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21635778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2167609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
2168609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2179475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
2180475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
22044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
22054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
22064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
22074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
22084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
22104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
22114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
22124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
22144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
22154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
22164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
22174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
22194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
22204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
22214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
22224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
22244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
22254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
22264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
22294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
22304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
22314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
22324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
22344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
22354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
22374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
22394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
22404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
22414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
22424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
22444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
22721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
22731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
2274ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2275ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
22765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
22775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
22785b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2279fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
22801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
22811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
22821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
22831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
2284c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2285c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
22864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
22874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
22885b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
22895b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
22901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2291fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2292fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2294ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2295fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
2296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
22987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
22997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
23027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
23032d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23065b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
23075b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23200e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
23357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
23387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
23397bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
234079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2343fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
2344fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (msg->findInt64("timestampNs", &timestampNs)) {
2345fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            info->mNotify->setInt64("timestampNs", timestampNs);
2346fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        } else {
2347fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
2348fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
2349fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
2350fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
2351fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
2352fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
235347aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
2354fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
2355fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
2356fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
2357fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2358fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
2361475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
2362475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    timestampNs, NULL, info->mFormat);
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
23867bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
238903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
239003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
239103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
239203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
239303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
239403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
239503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
239603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
239703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
239803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
239903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
240003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
24017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow(
24071a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian        const sp<Surface> &surfaceTextureClient) {
24087541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
24097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (mNativeWindow != NULL) {
24117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
24127541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
24137541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
24157541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
24167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
24177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
24187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow.clear();
24207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
24217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (surfaceTextureClient != NULL) {
24237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
24247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA);
24257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
24277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
24287541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
24297541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24307541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
24317541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
24327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24337541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        mNativeWindow = surfaceTextureClient;
24347541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
24357541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24367541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
24377541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
24387541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2439c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2440c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2441c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2442c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2443c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2444c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2445c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2446c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2447c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2448c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2459c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2468c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2470c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2471c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2472c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2473c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2474c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2475c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2476c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2478c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2479c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2480c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2481c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2482c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2483c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2484c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2485749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2486c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2487c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2488c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2489c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2490749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2491749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2492749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2493749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2494749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2495c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2498c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2499c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2500c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2501c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2502c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2503c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2504c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2505c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2506c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2507c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2508c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2509c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2510575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2511575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2512575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2513575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2514575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2515e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2516e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2517575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2518e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2519e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2520e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2521575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2522575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2523e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2524e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2525e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2526e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2527e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2528e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2529e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2530e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2531e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2532e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2533575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2534575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2535575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2536575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2537575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2538a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
25391d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2540a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2541a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2542a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2543a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2544a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2545a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2546a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2547a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2548a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2549a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2550a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2551a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2576a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
25932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
25942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
25952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
25962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
25972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
25982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
25992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
26002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
26012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
26022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
26042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
26052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
26062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
26082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
26092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
26102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
26112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
26122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
26142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
26152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
26162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2618