MediaCodec.cpp revision 47a2e875bdd2bd25cb8500208940ff1488b01e08
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>
31d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/IOMX.h>
3267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
365b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
37ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
402606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
416f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
42e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
435778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
44744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h>
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
46d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXClient.h>
47d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXCodec.h>
48d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
498b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar#include <media/stagefright/SurfaceUtils.h>
502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
53e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
545778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic inline int getCallingPid() {
5767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return IPCThreadState::self()->getCallingPid();
5867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
5967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic int64_t getId(sp<IResourceManagerClient> client) {
6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (int64_t) client.get();
6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) {
6547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    return (err == NO_MEMORY);
6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2;
6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient {
7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool reclaimResource() {
7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (codec == NULL) {
7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // codec is already gone.
7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            return true;
7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
7947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        status_t err = codec->reclaim();
8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK) {
8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
8267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
8367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (err == OK);
8467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
8567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
868f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    virtual String8 getName() {
878f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        String8 ret;
888f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
898f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec == NULL) {
908f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            // codec is already gone.
918f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            return ret;
928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu
948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        AString name;
958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec->getName(&name) == OK) {
968f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            ret.setTo(name.c_str());
978f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
988f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        return ret;
998f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    }
10067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected:
10267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual ~ResourceManagerClient() {}
10367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate:
10567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    wp<MediaCodec> mMediaCodec;
10667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
10867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu};
10967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
1112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    BatteryNotifier();
112d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    virtual ~BatteryNotifier();
1132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartVideo();
1152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopVideo();
1162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartAudio();
1172606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopAudio();
118d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    void onBatteryStatServiceDied();
1192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1202606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate:
121d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    struct DeathNotifier : public IBinder::DeathRecipient {
122d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        DeathNotifier() {}
123d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        virtual void binderDied(const wp<IBinder>& /*who*/) {
124d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            BatteryNotifier::getInstance().onBatteryStatServiceDied();
125d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
126d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    };
127d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
128d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex mLock;
1292606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mVideoRefCount;
1302606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mAudioRefCount;
1312606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    sp<IBatteryStats> mBatteryStatService;
132d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<DeathNotifier> mDeathNotifier;
133d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
134d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> getBatteryService_l();
135d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
136d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier);
1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang};
1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1392606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
1402606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1412606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() :
1422606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount(0),
1432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount(0) {
144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
145d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
146d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() {
147d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mBatteryStatService != NULL) {
148d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        return mBatteryStatService;
149d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
150d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // get battery service from service manager
1512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    const sp<IServiceManager> sm(defaultServiceManager());
1522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (sm != NULL) {
1532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        const String16 name("batterystats");
154d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mBatteryStatService =
155d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                interface_cast<IBatteryStats>(sm->getService(name));
1562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mBatteryStatService == NULL) {
1572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            ALOGE("batterystats service unavailable!");
158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            return NULL;
159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
160d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mDeathNotifier = new DeathNotifier();
16145c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang        IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier);
162d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        // notify start now if media already started
163d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mVideoRefCount > 0) {
164d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartVideo(AID_MEDIA);
165d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
166d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mAudioRefCount > 0) {
167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartAudio(AID_MEDIA);
168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    return mBatteryStatService;
171d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
172d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
173d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() {
174d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mDeathNotifier != NULL) {
175d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        IInterface::asBinder(mBatteryStatService)->
176d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                unlinkToDeath(mDeathNotifier);
1772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() {
181d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
182d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
183d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
184d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartVideo(AID_MEDIA);
1852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount++;
1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() {
190d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
1912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0) {
1922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
1932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
1942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
196d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
19745c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang
19845c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang    mVideoRefCount--;
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
220d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
22145c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang
22245c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang    mAudioRefCount--;
223d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
224d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopAudio(AID_MEDIA);
2252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
227d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
228d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() {
229d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
230d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mBatteryStatService.clear();
231d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mDeathNotifier.clear();
232d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // Do not reset mVideoRefCount and mAudioRefCount here. The ref
233d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // counting is independent of the battery service availability.
234d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // We need this if battery service becomes available after media
235d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // started.
236d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
237d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() {
23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
25467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
255e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu    IInterface::asBinder(mService)->linkToDeath(this);
25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int pid,
26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const sp<IResourceManagerClient> client,
26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->addResource(pid, clientId, client, resources);
27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
28167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->removeResource(clientId);
28267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
28367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
28467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
28567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int callingPid, const Vector<MediaResource> &resources) {
28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
28767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
28867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
28967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
29067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return mService->reclaimResource(callingPid, resources);
29167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
29267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2945778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
295251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
299251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
300251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
301251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
302251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3065778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
307251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *name, status_t *err) {
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
311251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
312251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
313251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
314251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
317d291c222357303b9611cab89d0c3b047584ef377Chong Zhang// static
318d291c222357303b9611cab89d0c3b047584ef377Chong Zhangsp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
319d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    OMXClient client;
320d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK_EQ(client.connect(), (status_t)OK);
321d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IOMX> omx = client.interface();
322d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
323d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
324d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferConsumer> bufferConsumer;
325d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
326d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = omx->createPersistentInputSurface(
327d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            &bufferProducer, &bufferConsumer);
328d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
329d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
330d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("Failed to create persistent input surface.");
331d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        return NULL;
332d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
333d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
334d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return new PersistentSurface(bufferProducer, bufferConsumer);
335d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
336d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
3375778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
33947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu      mReleasedByResourceManager(false),
3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
34192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
3427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
344251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
346ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
347ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerService(new ResourceManagerServiceProxy()),
3482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
3492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
35067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
35167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
3556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
3563d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
3573d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3605778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
36267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3813f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
38247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    int32_t finalErr = err;
38347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
38447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        // override the err code if MediaCodec has been released by ResourceManager.
38547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        finalErr = DEAD_OBJECT;
38647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
38747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
388c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
38947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    response->setInt32("err", finalErr);
390c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
391c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
392c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
393dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
39467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
39567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
396671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
397671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
398671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
399671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
400671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
405744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
406bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung    if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {
407744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new ACodec;
408744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else if (!nameIsType
409bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung            && !strncasecmp(name.c_str(), "android.filter.", 15)) {
410744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new MediaFilter;
411744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else {
412744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
413744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
414744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
41567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
416dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
41767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
4186f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
4196f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
4206f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
42167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
4226f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
4236f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
42460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
42548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        if (mcl == NULL) {
42648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            mCodec = NULL;  // remove the codec.
42748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            return NO_INIT; // if called from Java should raise IOException
42848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        }
4296f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
4306f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
43160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
43260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
43360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
43460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
43560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
43667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
43760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
4386f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
4396f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
4406f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
44467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
46967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
47067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
471c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
472c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
47367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
47467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
47567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
47667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
47767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
47867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
47967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
48067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
48167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
48267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
48367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
48467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
48567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
48667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
48767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
490c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
4911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
492c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
493c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
494c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
495c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
500f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        const sp<Surface> &surface,
5011bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
5031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
50967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
512f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    msg->setObject("surface", surface);
5131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
5141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
5151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
51967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
520f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
52167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
52367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
525c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
526c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
52767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
52867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
52967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
53067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
53167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
53267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
53367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
53467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
53567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
53667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
537f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
53867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
53967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
54067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
54167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
54267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
54367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
54467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
54567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
54667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
54767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
54867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
54967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
55167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
553f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
554f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
557d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t MediaCodec::usePersistentInputSurface(
558d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
559d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> msg = new AMessage(kWhatUsePersistentInputSurface, this);
560d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface.get());
561d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
562d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> response;
563d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return PostAndAwaitResponse(msg, &response);
564d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
565d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::setSurface(const sp<Surface> &surface) {
5671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
5681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
5691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
5711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return PostAndAwaitResponse(msg, &response);
5721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
5731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
5757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
5761d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
5777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
5797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
5807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
5817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
5827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
5837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
5847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
5857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
5867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
5877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
5887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
5897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
5907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
5917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
5927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() {
59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (!mIsVideo) {
59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return 0;
59767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
59967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    uint64_t size = 0;
60067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
60167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (size_t i = 0; i < portNum; ++i) {
60267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // TODO: this is just an estimation, we should get the real buffer size from ACodec.
60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return size;
60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
60767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
608c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wuvoid MediaCodec::addResource(const String8 &type, const String8 &subtype, uint64_t value) {
60967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
610c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(type, subtype, value));
61167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->addResource(
61267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources);
61367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
61467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
6161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
61867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
61967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
62067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
62167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
622c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
623c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
62467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
62567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
62667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
62767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
62867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
62967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
63067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
63167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
63267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
63367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Recover codec from previous error before retry start.
63467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = reset();
63567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
63667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to reset codec");
63767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
63867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
63967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            sp<AMessage> response;
64067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = PostAndAwaitResponse(mConfigureMsg, &response);
64167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
64267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to configure codec");
64367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
64467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
64567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
64667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
64767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
64867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
64967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
65067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
65167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
65267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
65367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
6545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6565778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
6571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
6585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
66347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wustatus_t MediaCodec::reclaim() {
66447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    sp<AMessage> msg = new AMessage(kWhatRelease, this);
66547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    msg->setInt32("reclaimed", 1);
66647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
66747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    sp<AMessage> response;
66847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    return PostAndAwaitResponse(msg, &response);
66947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu}
67047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
6721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
678671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
679671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
680671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
681671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
682671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
683671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
684671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
685671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
686671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
687671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
688671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
689671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
690671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
691671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
692671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
693671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
694671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
695671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
696671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
697251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
698671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
699671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
700671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
701671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
702671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
703671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
704671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
705671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
706671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
707671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
708dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
709671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
710671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
711671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
712671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
7135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
7185b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
7195b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
7205b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
7215b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
7225b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
7235b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
7305b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
7374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
7384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
7394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
7404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
7414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
7424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
7434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
7444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
7455b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
7465b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
7475b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
7485b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
7495b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
7505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7511d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
7524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
7534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
7544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
7554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
7564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
7574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
7584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
7594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
7604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
7615b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
7624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
7645b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
7655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7665b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
7674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
7684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
7701d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
7911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
8101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
818fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
8191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
820fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
821fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
822fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
823fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
824fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
825fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
826fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
827fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
8285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
8291d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
8305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
8315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
8371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
8387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
8397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
8407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
8417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
8427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
8435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
8441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
8581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
865e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
870e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
871717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
8721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
873717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
874717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
875717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
876717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
877717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
878717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
879717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
880717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
881717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
882717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
883717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
884717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
885e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const {
886e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
887e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("portIndex", kPortIndexInput);
888e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setPointer("buffers", buffers);
889e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("widevine", true);
890e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
891e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> response;
892e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    return PostAndAwaitResponse(msg, &response);
893e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar}
894e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
8955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
8961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
9051d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9137bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
9147bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
9157bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
9167bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9177bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9187bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
9197bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
9207bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
9217bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9227bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
9247bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
9257bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
9267bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9277bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9280e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
9290e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
9300e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
9310e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
9327bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
9337bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
9347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
9357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
9367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
93747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
93847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        return DEAD_OBJECT;
93947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
94047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
9417bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
9427bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
9430e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
9447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
9457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
9467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
9487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
9497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
9507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
9517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
9527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
9537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
9540837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            // by the time buffers array is initialized, crypto is set
9550837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            if (portIndex == kPortIndexInput && mCrypto != NULL) {
9560837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mEncryptedData;
9570837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            } else {
9580837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mData;
9590837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            }
9607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
9617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
9627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
9637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
9647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
9671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
973496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
9741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
975496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
976496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
977496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
978496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
979575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
9801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
981575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
982575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
983575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
984575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9875778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
989c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
997c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10053f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
10060e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
1008c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
1010251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
1011251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
1012251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
10300e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
103247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INVALID_OPERATION);
1033251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
103447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, getStickyError());
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
103647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
103947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
104247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        sp<AMessage> response = new AMessage;
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
107747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        response->postReply(replyID);
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
109192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1093251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1094251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1095251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10979e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
10989e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1099251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1100aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
110152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1102aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1103aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
11045530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
11075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1115c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1116c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1122c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1123c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
1128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11335530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
113403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
1135aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
113603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
113703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
113803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
113903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
114003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
114103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
114203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
114303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
11446e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
11456e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
11466e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
114703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
114803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11549e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
11559e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
11569e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
11579e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
11589e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
11599e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11665530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1168251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1169575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1172c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1173c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1174251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1175251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1176251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1177251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1178251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1179251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1180251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1181251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1182251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1183251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1184251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1185c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11915530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1193251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1194575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1195c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1196251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1197251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1198251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1199251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1200c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1201251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1202251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1203251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1204251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1205251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1206251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1207251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1208251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1209251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1210251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1211251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1212c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12175530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1218251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
122392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
122752dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1229717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1231717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
12323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
12343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
123767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    String8 resourceType;
1238717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
12391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
124067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceSecureCodec);
12411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
12421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
124367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceNonSecureCodec);
12441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
1245c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu
1246c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
1247c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    addResource(resourceType, String8(subtype), 1);
12481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
125392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
12586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
12596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1260e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1261e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1262e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
12643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
12653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
12663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
12682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
127392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
12747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
127592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
12767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
12771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
12787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
12797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
12807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
12817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
12827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
12836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
12847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
12857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1291d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                case CodecBase::kWhatInputSurfaceAccepted:
1292d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                {
1293d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    // response to initiateUsePersistentInputSurface()
1294d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    status_t err = NO_ERROR;
1295d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    sp<AMessage> response = new AMessage();
1296d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    if (!msg->findInt32("err", &err)) {
1297d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        mHaveInputSurface = true;
1298d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    } else {
1299d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        response->setInt32("err", err);
1300d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    }
1301d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    response->postReply(mReplyID);
1302d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    break;
1303d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                }
1304d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
130592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
13067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
130792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
13081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
13097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
13107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
13117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
13127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
13137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
13147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
13157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
13167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
13177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
131892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13207bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1334eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1335eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1336eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
133792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
133892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1340eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1342c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1343c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1344c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1345c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1346c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1347c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1348c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1349c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1350c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1351c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1352c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1353eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1355eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1357eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1360c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1361ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
1362c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                                new ABuffer(mem->pointer(), info.mData->capacity());
1363c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1364ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1365ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
137467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            if (mIsVideo) {
1375c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                String8 subtype;
1376c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                addResource(
1377c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        String8(kResourceGraphicMemory),
1378c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        subtype,
1379c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        getGraphicBufferSize());
138067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            }
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1385575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
139192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1395475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1396f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                            mSurface != NULL &&
13973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1401475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1402f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                            mSoftRenderer = new SoftwareRenderer(mSurface);
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
1407e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1408e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1409e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1413c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1414c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
14192514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
14202514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
14212514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
14228140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
14238140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
14248140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
14258140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
14268140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
14278140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
14288140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
14292514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
14302514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
143492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1438c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
14468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
14478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
14488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
14508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
14518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
14528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
14538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
14548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
14568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
14588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
14598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
14608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1461251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1462575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1463575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
14658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
14668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
14678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
14688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
14706e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
14713d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
14723d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
14733d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
14743d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
14753d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
14766e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1483575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1484575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
148992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1494c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15002d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
15012d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1524c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1525c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1526c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1527c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1528c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1531c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1532c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1533c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1539575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1540575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1542575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
154692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
155392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1555c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1557c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
15606e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1561c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
156252dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
156467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
156567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
157092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15725530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
15735530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
15745530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
15755530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
15765530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15780e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
15790e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
15800e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
15810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
15820e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
15830e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15973f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1601c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
16130db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
16140db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1631c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1632c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
16333f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1635c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1636c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1637c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
16380e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
16390e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1640c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1641c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1642c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1643c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1644c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1645c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1646c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1647c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1648c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1649c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1650c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1651c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1652c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1653c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1654c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1655c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1656c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1657c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1658c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1659c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1660c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1661c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1662c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16653f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1669c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
1674f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar            CHECK(msg->findObject("surface", &obj));
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16798b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            int32_t push;
16808b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
16818b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                mFlags |= kFlagPushBlankBuffersOnShutdown;
16828b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
16838b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
1686f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                status_t err = handleSetSurface(static_cast<Surface *>(obj.get()));
16877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1688c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
16897541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
16901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
16911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
1692f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                handleSetSurface(NULL);
16931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
16941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
16967541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
16977541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
16991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
17001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
17041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
17148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case kWhatSetSurface:
17201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
17211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
17221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
17231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            status_t err = OK;
17251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<Surface> surface;
17261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            switch (mState) {
17281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case CONFIGURED:
17291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case STARTED:
17301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case FLUSHED:
17311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                {
17321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<RefBase> obj;
17331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    (void)msg->findObject("surface", &obj);
17341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<Surface> surface = static_cast<Surface *>(obj.get());
17351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    if (mSurface == NULL) {
17361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support setting surface if it was not set
17371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = INVALID_OPERATION;
17381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else if (obj == NULL) {
17391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support unsetting surface
17401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = BAD_VALUE;
17411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else {
17421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = connectToSurface(surface);
17431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        if (err == BAD_VALUE) {
17441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            // assuming reconnecting to same surface
17451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            // TODO: check if it is the same surface
17461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            err = OK;
17471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        } else {
17481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
17491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                if (mFlags & kFlagUsesSoftwareRenderer) {
17508b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    if (mSoftRenderer != NULL
17518b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                            && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
17528b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                        pushBlankBuffersToNativeWindow(mSurface.get());
17538b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    }
17541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    mSoftRenderer = new SoftwareRenderer(surface);
17551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    // TODO: check if this was successful
17561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                } else {
17571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    err = mCodec->setSurface(surface);
17581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                }
17591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
17601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
17611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                (void)disconnectFromSurface();
17621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                mSurface = surface;
17631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
17641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        }
17651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    }
17661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
17671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
17681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                default:
17701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    err = INVALID_OPERATION;
17711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
17721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
17731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            PostReplyWithError(replyID, err);
17751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
17761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
17771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
1779d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case kWhatUsePersistentInputSurface:
17807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
17813f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
17837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
17847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
17857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1786c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
17887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
17897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
17907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
1791d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            if (msg->what() == kWhatCreateInputSurface) {
1792d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->initiateCreateInputSurface();
1793d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            } else {
1794d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                sp<RefBase> obj;
1795d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                CHECK(msg->findObject("input-surface", &obj));
1796d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
1797d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->initiateUsePersistentInputSurface(
1798d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        static_cast<PersistentSurface *>(obj.get()));
1799d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            }
18007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
18017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18043f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1808d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
18093d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
18103d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
18113d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
18123d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
18130e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
18140e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1815d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
18160e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1817c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1831aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1832aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1833aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
18343f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1835c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
183747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            // already stopped/released
183847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (mState == UNINITIALIZED && mReleasedByResourceManager) {
183947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                sp<AMessage> response = new AMessage;
184047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->setInt32("err", OK);
184147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->postReply(replyID);
184247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                break;
184347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
184447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
184547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            int32_t reclaimed = 0;
184647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            msg->findInt32("reclaimed", &reclaimed);
184747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (reclaimed) {
184847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                mReleasedByResourceManager = true;
184947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
185047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
185133223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
185233223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
18530e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
185433223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
185533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
185633223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
185752dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
185803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
185903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
186003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
186103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
186203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1863c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
186447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
186547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // the previous stop/release completes and then reply with OK.
18666e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
18676e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
18686e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
18696e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
18706e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1871c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1872c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1873c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1874c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1875aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1876aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1877aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1878aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
18796e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
18806e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
18816e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1882aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1883aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1884aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1885aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1886c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1887aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1888aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1889aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1890aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1891c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
18938b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
18948b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
18958b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                pushBlankBuffersToNativeWindow(mSurface.get());
18968b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1905c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1906c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1907c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1908c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1909c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1910c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
19116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
19126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1913c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
19156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
19166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1925c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
19341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1954c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19633f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1966251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1967c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1969251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1970251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1971251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1976c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19823f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1985c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1986c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1987c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1988c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1989c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1990c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1999c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
20081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2028c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20373f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2040251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2041c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2043251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2044251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2045251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2050c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
20557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
20563f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
20587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2059251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2060c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
2062251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2063251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2064251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
20667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
20677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
20687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
20697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
20707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
20717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20743f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2076e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // Unfortunately widevine legacy source requires knowing all of the
2077e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // codec input buffers, so we have to provide them even in async mode.
2078e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            int32_t widevine = 0;
2079e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            msg->findInt32("widevine", &widevine);
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2081e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
2082c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2084251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2085251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2086251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2101ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
21021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
2103ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
21123f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2116c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
21240e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2132e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
2135e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
2136e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
2137e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
21383f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2141e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
21420e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
21430e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
2144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
2145c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2147251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2148251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2149251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
2153e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2158496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
2159496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
2160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
2161496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
2162496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
2163496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2164575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
2165575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
2166575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
2167575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
2168575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2169575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
2170575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
2171575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
2172575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2173717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2174717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
21753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2176717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2177717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2178717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2179c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2180717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2181717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2182717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2183717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2184717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2185717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2186717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2187717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2188717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2189a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2190a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
21913f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2192a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2193a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2194a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2195a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2196a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2197a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2198a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2199c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2200a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2201a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2202a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22088ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
22098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
22108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
22128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
22138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2214a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
22158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
22168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
22178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
22198ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
22208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
22218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2222a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
22238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
22248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
22268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
22278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22287bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
22297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
22308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
22328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
22338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
22358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
22368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
22388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
22398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
22408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
22428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
22448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
22468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
22478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
22488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
22498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
22508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
22518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
22528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
22548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
22558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22565778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
22577541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
2262f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        handleSetSurface(NULL);
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2264671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2269e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2270e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
2271c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2272251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2273575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2274575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2275c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2278717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2279671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2280671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2281671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2282aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2283aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2284aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2285aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2286717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2287717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
22912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
22922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22955778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23005778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
23027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
23157fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
23167fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23255778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2329609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
2330609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2341475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
2342475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
23664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
23674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
23684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
23694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
23704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
23724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
23734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
23744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
23764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
23774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
23784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
23794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
23814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
23824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
23834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
23844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
23854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
23864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
23874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
23884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
23894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
23914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
23924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
23934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
23944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
23964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
23974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
23994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
24014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
24024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
24034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
24044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
24054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
24064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
24341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
24351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
2436ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2437ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
24385b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
24395b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
24405b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2441fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
24421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
24431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
24441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
24451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
2446c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2447c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
24484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
24494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
24505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
24515b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
24521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2453fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2454fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2455ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2456ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2457fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
2458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
24607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
24617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
24627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
24637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
24647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
24652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24685b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
24695b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24820e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
24977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
24987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
24997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
25007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
25017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
250279ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2505fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
2506fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (msg->findInt64("timestampNs", &timestampNs)) {
2507fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            info->mNotify->setInt64("timestampNs", timestampNs);
2508fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        } else {
2509fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
2510fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
2511fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
2512fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
2513fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
2514fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
251547aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
2516fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
2517fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
2518fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
2519fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2520fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
2523475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
2524475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    timestampNs, NULL, info->mFormat);
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25345778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
25487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
25497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
25507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
255103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
255203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
255303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
255403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
255503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
255603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
255703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
255803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
255903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
256003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
256103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
256203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
25637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
25691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
25701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface != NULL) {
25711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
25721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err == BAD_VALUE) {
25731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGI("native window already connected. Assuming no change of surface");
25741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        } else if (err != OK) {
25751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
25761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
25771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
25781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
25791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
25807541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
25811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::disconnectFromSurface() {
25821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
2583f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (mSurface != NULL) {
25841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
25857541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
25861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("native_window_api_disconnect returned an error: %s (%d)", strerror(-err), err);
25877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
25881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // assume disconnected even on error
2589f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        mSurface.clear();
25907541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
25911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
25921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
25937541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
25941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::handleSetSurface(const sp<Surface> &surface) {
25951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
25961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mSurface != NULL) {
25971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)disconnectFromSurface();
25981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
2599f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (surface != NULL) {
26001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = connectToSurface(surface);
26011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err == OK) {
26021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mSurface = surface;
26037541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
26047541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
26051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
26067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
26077541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2608c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2609c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2610c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2611c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2612c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2613c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2614c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2615c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2616c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2617c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2618c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2619c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2620c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2621c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2622c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2623c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2624c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2625c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2626c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2627c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2628c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2629c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2630c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2631c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2632c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2633c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2635c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2636c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2637c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2638c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2639c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2640c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2641c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2642c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2643c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2644c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2645c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2646c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2647c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2648c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2649c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2650c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2651c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2652c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2653c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2654749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2655c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2656c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2657c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2658c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2659749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2660749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2661749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2662749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2663749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2664c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2665c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2666c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2667c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2668c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2669c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2670c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2671c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2672c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2673c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2674c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2675c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2676c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2677c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2678c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2679575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2680575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2681575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2682575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2683575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2684e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2685e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2686575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2687e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2688e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2689e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2690575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2691575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2692e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2693e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2694e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2695e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2696e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2697e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2698e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2699e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2700e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2701e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2702575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2703575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2704575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2705575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2706575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2707a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
27081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2709a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2710a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2711a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2712a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2713a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2714a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2715a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2716a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2717a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2718a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2719a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2720a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2745a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2747e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2748e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2749e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2750e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2751e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
27622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
27632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
27642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
27652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
27672606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
27682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
27692606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
27702606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
27712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27722606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
27732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
27742606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
27752606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27762606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
27772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
27782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
27792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
27802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
27812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
27832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
27842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
27852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2787