MediaCodec.cpp revision d291c222357303b9611cab89d0c3b047584ef377
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>
492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
52e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
535778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic inline int getCallingPid() {
5667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return IPCThreadState::self()->getCallingPid();
5767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
5867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic int64_t getId(sp<IResourceManagerClient> client) {
6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (int64_t) client.get();
6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) {
6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (err == OMX_ErrorInsufficientResources);
6567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2;
6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient {
7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool reclaimResource() {
7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (codec == NULL) {
7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // codec is already gone.
7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            return true;
7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        status_t err = codec->release();
7967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK) {
8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
8267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (err == OK);
8367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
8467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
858f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    virtual String8 getName() {
868f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        String8 ret;
878f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
888f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec == NULL) {
898f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            // codec is already gone.
908f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            return ret;
918f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu
938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        AString name;
948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec->getName(&name) == OK) {
958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            ret.setTo(name.c_str());
968f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
978f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        return ret;
988f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    }
9967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected:
10167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual ~ResourceManagerClient() {}
10267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate:
10467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    wp<MediaCodec> mMediaCodec;
10567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
10767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu};
10867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
1092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> {
1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    BatteryNotifier();
111d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    virtual ~BatteryNotifier();
1122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartVideo();
1142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopVideo();
1152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStartAudio();
1162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    void noteStopAudio();
117d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    void onBatteryStatServiceDied();
1182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate:
120d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    struct DeathNotifier : public IBinder::DeathRecipient {
121d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        DeathNotifier() {}
122d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        virtual void binderDied(const wp<IBinder>& /*who*/) {
123d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            BatteryNotifier::getInstance().onBatteryStatServiceDied();
124d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
125d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    };
126d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
127d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex mLock;
1282606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mVideoRefCount;
1292606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    int32_t mAudioRefCount;
1302606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    sp<IBatteryStats> mBatteryStatService;
131d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<DeathNotifier> mDeathNotifier;
132d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
133d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> getBatteryService_l();
134d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
135d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier);
1362606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang};
1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier)
1392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1402606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() :
1412606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount(0),
1422606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount(0) {
143d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
145d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() {
146d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mBatteryStatService != NULL) {
147d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        return mBatteryStatService;
148d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
149d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // get battery service from service manager
1502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    const sp<IServiceManager> sm(defaultServiceManager());
1512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (sm != NULL) {
1522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        const String16 name("batterystats");
153d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mBatteryStatService =
154d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                interface_cast<IBatteryStats>(sm->getService(name));
1552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mBatteryStatService == NULL) {
1562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            ALOGE("batterystats service unavailable!");
157d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            return NULL;
158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        mDeathNotifier = new DeathNotifier();
16045c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang        IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier);
161d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        // notify start now if media already started
162d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mVideoRefCount > 0) {
163d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartVideo(AID_MEDIA);
164d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
165d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        if (mAudioRefCount > 0) {
166d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang            mBatteryStatService->noteStartAudio(AID_MEDIA);
167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        }
168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    }
169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    return mBatteryStatService;
170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
171d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
172d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() {
173d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mDeathNotifier != NULL) {
174d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        IInterface::asBinder(mBatteryStatService)->
175d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang                unlinkToDeath(mDeathNotifier);
1762606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() {
180d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
181d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
182d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
183d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartVideo(AID_MEDIA);
1842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mVideoRefCount++;
1862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() {
189d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
1902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mVideoRefCount == 0) {
1912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): video refcount is broken!");
1922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
1932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
1942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
195d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
19645c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang
19745c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang    mVideoRefCount--;
198d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mVideoRefCount == 0 && batteryService != NULL) {
199d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopVideo(AID_MEDIA);
2002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
2022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
2032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() {
204d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
205d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
206d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
207d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStartAudio(AID_MEDIA);
2082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    mAudioRefCount++;
2102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
2112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
2122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() {
213d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
2142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mAudioRefCount == 0) {
2152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!");
2162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return;
2172606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
219d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    sp<IBatteryStats> batteryService = getBatteryService_l();
22045c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang
22145c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang    mAudioRefCount--;
222d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    if (mAudioRefCount == 0 && batteryService != NULL) {
223d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang        batteryService->noteStopAudio(AID_MEDIA);
2242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
2252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
226d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
227d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() {
228d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    Mutex::Autolock _l(mLock);
229d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mBatteryStatService.clear();
230d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    mDeathNotifier.clear();
231d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // Do not reset mVideoRefCount and mAudioRefCount here. The ref
232d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // counting is independent of the battery service availability.
233d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // We need this if battery service becomes available after media
234d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang    // started.
235d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang}
236d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang
23767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() {
23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
254e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu    IInterface::asBinder(mService)->linkToDeath(this);
25567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int pid,
26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const sp<IResourceManagerClient> client,
26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->addResource(pid, clientId, client, resources);
27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService->removeResource(clientId);
28167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
28267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
28367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
28467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int callingPid, const Vector<MediaResource> &resources) {
28567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
28767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
28867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
28967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return mService->reclaimResource(callingPid, resources);
29067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
29167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2935778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
294251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) {
2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
297251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
299251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
300251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
301251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3055778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
306251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        const sp<ALooper> &looper, const char *name, status_t *err) {
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<MediaCodec> codec = new MediaCodec(looper);
3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
309251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
311251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
312251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
313251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
316d291c222357303b9611cab89d0c3b047584ef377Chong Zhang// static
317d291c222357303b9611cab89d0c3b047584ef377Chong Zhangsp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
318d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    OMXClient client;
319d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK_EQ(client.connect(), (status_t)OK);
320d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IOMX> omx = client.interface();
321d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
322d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
323d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferConsumer> bufferConsumer;
324d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
325d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = omx->createPersistentInputSurface(
326d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            &bufferProducer, &bufferConsumer);
327d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
328d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
329d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("Failed to create persistent input surface.");
330d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        return NULL;
331d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
332d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
333d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return new PersistentSurface(bufferProducer, bufferConsumer);
334d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
335d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
3365778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper)
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
33992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
3407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
342251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
344ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
345ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerService(new ResourceManagerServiceProxy()),
3462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
3472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
34867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
34967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
3536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
3543d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
3553d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3585778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
36067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
379c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static
3803f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
381c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
382c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->setInt32("err", err);
383c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
384c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
385c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
386dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
38767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
38867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
389671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
390671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
391671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
392671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
393671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
398744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
399bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung    if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {
400744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new ACodec;
401744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else if (!nameIsType
402bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung            && !strncasecmp(name.c_str(), "android.filter.", 15)) {
403744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new MediaFilter;
404744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else {
405744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
406744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
407744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
40867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
409dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
41067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
4116f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
4126f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
4136f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
41467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
4156f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
4166f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
41760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
41848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        if (mcl == NULL) {
41948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            mCodec = NULL;  // remove the codec.
42048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            return NO_INIT; // if called from Java should raise IOException
42148a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        }
4226f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
4236f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
42460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
42560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
42660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
42760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
42860b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
42967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
43060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
4316f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
4326f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
4336f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
43667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
43767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
4405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4511d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4531d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
46167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
46267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
46367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
464c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
465c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
46667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
46767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
46867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
46967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
47067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
47167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
47267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
47367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
47467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
47567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
47667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
47767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
47867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
47967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
48067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
483c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
4841d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
485c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
486c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
487c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
488c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
489c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
490c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
493f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        const sp<Surface> &surface,
4941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
4961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
49867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
49967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
50067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
50167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
50267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
505f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    msg->setObject("surface", surface);
5061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
5071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
5081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
5095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
51167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
51267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
513f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
51467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
51567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
51667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
51767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
518c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
519c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
52067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
52167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
52367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
52567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
52667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
52767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
52867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
52967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
530f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
53167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
53267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
53367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
53467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
53567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
53667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
53767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
53867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
53967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
54067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
54167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
54267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
54367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
54467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
54567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
546f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
547f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
5485778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
550d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t MediaCodec::usePersistentInputSurface(
551d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
552d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> msg = new AMessage(kWhatUsePersistentInputSurface, this);
553d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface.get());
554d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
555d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> response;
556d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return PostAndAwaitResponse(msg, &response);
557d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
558d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
5597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
5607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
5611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
5627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
5647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
5657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
5667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
5677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
5687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
5697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
5707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
5717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
5727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
5737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
5747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
5757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
5767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
5777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() {
58067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (!mIsVideo) {
58167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return 0;
58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
58467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    uint64_t size = 0;
58567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
58667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (size_t i = 0; i < portNum; ++i) {
58767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // TODO: this is just an estimation, we should get the real buffer size from ACodec.
58867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
58967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
59067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return size;
59167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
59267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
593c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wuvoid MediaCodec::addResource(const String8 &type, const String8 &subtype, uint64_t value) {
59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
595c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(type, subtype, value));
59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->addResource(
59767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources);
59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
59967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
6011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
607c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
608c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
60967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
61067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
61167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
61267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
61367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
61467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
61567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) {
61667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
61767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
61867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Recover codec from previous error before retry start.
61967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = reset();
62067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
62167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to reset codec");
62267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
62367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
62467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            sp<AMessage> response;
62567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = PostAndAwaitResponse(mConfigureMsg, &response);
62667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
62767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to configure codec");
62867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
62967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
63067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
63167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
63267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
63367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
63467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
63567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
63667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
63767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
63867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
6395778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
6421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
6435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6465778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
648c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
6491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
650c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
651c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
653c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
654c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
655671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
656671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
657671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
658671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
659671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
660671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
661671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
662671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
663671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
664671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
665671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
666671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
667671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
668671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
669671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
670671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
671671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
672671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
673671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
674251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
675671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
676671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
677671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
678671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
679671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
680671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
681671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
682671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
683671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
684671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
685dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
686671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
687671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
688671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
689671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
6945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
6955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6975b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6985b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
7005b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
7025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
7055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
7075b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
7144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
7154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
7164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
7174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
7184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
7194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
7204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
7214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
7225b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
7235b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
7245b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
7255b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
7265b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
7275b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
7294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
7304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
7314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
7324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
7334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
7344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
7354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
7364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
7374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
7385b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
7394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
7415b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
7425b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7435b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
7444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
7454b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
7471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
7681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
7695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
7871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
795fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
7961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
797fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
798fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
799fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
800fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
801fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
802fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
803fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
804fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
8061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
8141d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
8157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
8167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
8177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
8187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
8197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
8205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
8211d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
8225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
8255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
8305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
834e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
8351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
836e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
837e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
838e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
848717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
8491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
850717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
851717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
852717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
853717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
854717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
855717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
856717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
857717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
858717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
859717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
860717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
861717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
862e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const {
863e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
864e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("portIndex", kPortIndexInput);
865e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setPointer("buffers", buffers);
866e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("widevine", true);
867e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
868e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> response;
869e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    return PostAndAwaitResponse(msg, &response);
870e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar}
871e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
8725778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
8731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
8755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
8821d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
8845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
8917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
8937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8947bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
8967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
8977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
8987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
9017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
9027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
9037bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9047bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9050e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
9060e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
9070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
9080e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
9097bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
9107bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
9117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
9127bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
9137bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9147bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
9157bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
9160e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
9177bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
9187bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
9197bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9207bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
9217bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
9227bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
9237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
9247bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
9257bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
9267bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
9270837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            // by the time buffers array is initialized, crypto is set
9280837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            if (portIndex == kPortIndexInput && mCrypto != NULL) {
9290837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mEncryptedData;
9300837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            } else {
9310837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mData;
9320837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            }
9337bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
9347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
9357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
9367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
9377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
9401d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
946496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
9471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
948496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
949496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
950496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
951496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
952575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
9531d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
954575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
955575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
956575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
957575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9605778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
962c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
970c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9783f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9790e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
981c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
983251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
984251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
985251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10050e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INVALID_OPERATION);
1008251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
1009251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        response->setInt32("err", getStickyError());
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED);
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("err", INFO_FORMAT_CHANGED);
10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10585778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
106692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1068251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1069251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1070251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10729e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
10739e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1074251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1075aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
107652dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1077aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1078aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
10795530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1090c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1091c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1097c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1098c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
1103c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
11075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11085530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
110903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
1110aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
111103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
111203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
111303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
111403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
111503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
111603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
111703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
111803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
11196e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
11206e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
11216e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
112203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
112303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11299e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
11309e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
11319e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
11329e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
11339e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
11349e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11380e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11415530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1143251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1144575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1147c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1148c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1149251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1152251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1153251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1154251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1155251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1156251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1157251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1158251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1159251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1160c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11665530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1168251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1169575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1170c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1171251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1172251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1173251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1174251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1175c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1176251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1177251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1178251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1179251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1180251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1181251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1182251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1183251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1184251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1185251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1186251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1187c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11925530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1193251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
119892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
120252dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1204717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1206717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
12073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
12093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
121267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    String8 resourceType;
1213717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
12141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
121567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceSecureCodec);
12161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
12171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
121867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceNonSecureCodec);
12191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
1220c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu
1221c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
1222c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    addResource(resourceType, String8(subtype), 1);
12231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
122892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12326507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
12336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
12346507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1235e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1236e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1237e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12383a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
12393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
12403a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
12413a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12423a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
12432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
124892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
12497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
125092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
12517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
12527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
12537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
12547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
12557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
12567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
12577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
12586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
12597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
12607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1266d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                case CodecBase::kWhatInputSurfaceAccepted:
1267d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                {
1268d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    // response to initiateUsePersistentInputSurface()
1269d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    status_t err = NO_ERROR;
1270d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    sp<AMessage> response = new AMessage();
1271d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    if (!msg->findInt32("err", &err)) {
1272d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        mHaveInputSurface = true;
1273d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    } else {
1274d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        response->setInt32("err", err);
1275d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    }
1276d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    response->postReply(mReplyID);
1277d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    break;
1278d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                }
1279d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
128092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
12817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
128292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
12837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    sp<AMessage> response = new AMessage();
12847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
12857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
12867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
129392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1309eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1310eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1311eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
131292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
131392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1315eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1317c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1318c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1319c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1320c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1321c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1322c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1323c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1324c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1325c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1326c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1327c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1328eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1330eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1332eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1335c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1336ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
1337c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                                new ABuffer(mem->pointer(), info.mData->capacity());
1338c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1339ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1340ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
134967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            if (mIsVideo) {
1350c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                String8 subtype;
1351c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                addResource(
1352c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        String8(kResourceGraphicMemory),
1353c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        subtype,
1354c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        getGraphicBufferSize());
135567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            }
13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1360575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
136692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1370475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1371f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                            mSurface != NULL &&
13723a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1376475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1377f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                            mSoftRenderer = new SoftwareRenderer(mSurface);
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
1382e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1383e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1384e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1385e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1386e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1387e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1388c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1389c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1390e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1391e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1393e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
13942514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13952514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
13962514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
13978140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
13988140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
13998140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
14008140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
14018140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
14028140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
14038140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
14042514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
14052514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
140992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1413c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1414c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1415c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
14218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
14228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
14238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
14258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
14268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
14278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
14288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
14298ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
14318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
14338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
14348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
14358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1436251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1437575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1438575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
14408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
14418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
14428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
14438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1444c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
14456e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
14463d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
14473d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
14483d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
14493d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
14503d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
14516e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1458575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1459575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
146492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14752d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
14762d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1483e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1484e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1485e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1486e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1487e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1488e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1489e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1490e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1491e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1492e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1493e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1494e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1495e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1496e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1497e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1498e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1499c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1500c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1501c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1502c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1503c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1504e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1505e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1506c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1507c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1508c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1514575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1515575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1517575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
152192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
152892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1530c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1531c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1532c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1533c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1534c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
15356e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1536c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
153752dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
153967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
154067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
154592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15475530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
15485530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
15495530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
15505530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
15515530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15530e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
15540e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
15550e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
15560e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
15570e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
15580e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15723f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1576c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
15825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
15880db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
15890db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1606c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1607c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
16083f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1609c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1610c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1611c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1612c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
16130e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
16140e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1615c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1616c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1617c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1618c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1619c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1620c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1621c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1622c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1623c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1624c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1625c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1626c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1627c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1628c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1629c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1630c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1631c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1632c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1633c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1635c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1636c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1637c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16403f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1644c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
1649f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar            CHECK(msg->findObject("surface", &obj));
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
1656f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                status_t err = handleSetSurface(static_cast<Surface *>(obj.get()));
16577541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1658c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
16597541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
16601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
16611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
1662f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                handleSetSurface(NULL);
16631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
16641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16657541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
16667541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
16677541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
16691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
16701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
16741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1680e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
16848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
1690d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        case kWhatUsePersistentInputSurface:
16917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
16923f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
16947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
16957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
16967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1697c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
16997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
17007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
17017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
1702d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            if (msg->what() == kWhatCreateInputSurface) {
1703d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->initiateCreateInputSurface();
1704d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            } else {
1705d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                sp<RefBase> obj;
1706d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                CHECK(msg->findObject("input-surface", &obj));
1707d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
1708d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->initiateUsePersistentInputSurface(
1709d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        static_cast<PersistentSurface *>(obj.get()));
1710d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            }
17117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
17127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
17135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17153f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17180e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1719d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
17203d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
17213d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
17223d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
17233d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
17240e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
17250e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1726d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
17270e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1728c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
17335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1740c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1741c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1742aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1743aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1744aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
17453f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1746c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1747c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
174833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
174933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
17500e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
175133223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
175233223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
175333223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
175452dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
175503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
175603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
175703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
175803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
175903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1760c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
17616e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
17626e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
17636e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
17646e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
17656e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1766c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1768c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1769c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1770aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1771aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1772aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1773aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
17746e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
17756e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
17766e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1777aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1778aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1779aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1780aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1781c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1782aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1783aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1784aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1785aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1786c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17933f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1796c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1797c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1798c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1799c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1800c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1801c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
18026507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
18036507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1804c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
18066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
18076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
18145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1816c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
18251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1845c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18543f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1857251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1858c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1860251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1861251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1862251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1867c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18733f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1876c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1877c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1878c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1879c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1880c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1881c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1890c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
18991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1919c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19283f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1931251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1932c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1934251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1935251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1936251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1941c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
19467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
19473f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
19497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1950251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1951c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
1953251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1954251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1955251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
19577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
19587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
19597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
19607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
19617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
19627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19653f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1967e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // Unfortunately widevine legacy source requires knowing all of the
1968e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // codec input buffers, so we have to provide them even in async mode.
1969e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            int32_t widevine = 0;
1970e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            msg->findInt32("widevine", &widevine);
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1972e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
1973c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1975251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1976251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1977251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1992ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
19931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
1994ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20033f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2006251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2007c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2009251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2010251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2011251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
20150e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2023e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
2026e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
2027e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
2028e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
20293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2032e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
20330e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
20340e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
2035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
2036c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2038251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2039251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2040251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
2044e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2049496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
2050496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
2051496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
2052496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
2053496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
2054496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2055575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
2056575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
2057575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
2058575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
2059575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2060575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
2061575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
2062575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
2063575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2064717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2065717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
20663f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2067717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2068717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2069717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2070c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2071717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2072717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2073717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2074717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2075717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2076717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2077717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2078717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2079717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2080a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2081a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
20823f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2083a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2084a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2085a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2086a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2087a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2088a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2089a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2090c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2091a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2092a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2093a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20998ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
21008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
21018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
21038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
21048ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2105a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
21068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
21078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
21088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
21108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
21118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
21128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2113a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
21148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
21158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
21178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
21188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21197bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
21207bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
21218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
21238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
21248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
21268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
21278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
21298ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
21308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
21318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
21338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
21358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21361d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
21378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
21388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
21398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
21408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
21418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
21428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
21438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
21458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
21468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21475778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
21487541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
2153f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        handleSetSurface(NULL);
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2155671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2160e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2161e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
2162c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2163251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2164575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2165575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2166c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2169717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2170671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2171671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2172671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2173aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2174aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2175aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2176aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2177717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2178717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
21822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
21832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21865778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21915778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
21937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
22067fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
22077fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22165778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2220609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
2221609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2232475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
2233475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
22574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
22584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
22594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
22604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
22614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
22634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
22644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
22654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
22674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
22684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
22694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
22704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
22724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
22734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
22744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
22754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
22774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
22784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
22794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
22824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
22834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
22844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
22854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
22874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
22884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
22904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
22924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
22934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
22944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
22954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
22964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
22974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
23251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
23261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
2327ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2328ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
23295b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
23305b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
23315b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2332fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
23331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
23341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
23351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
23361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
2337c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2338c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
23394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
23404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
23415b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
23425b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
23431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2344fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2345fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2346ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2347ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2348fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
2349ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2350ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
23517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
23527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
23557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
23562d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23595b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
23605b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23730e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
23887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
23897bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
23907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
23917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
23927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
239379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2396fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        int64_t timestampNs = 0;
2397fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        if (msg->findInt64("timestampNs", &timestampNs)) {
2398fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            info->mNotify->setInt64("timestampNs", timestampNs);
2399fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        } else {
2400fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // TODO: it seems like we should use the timestamp
2401fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // in the (media)buffer as it potentially came from
2402fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // an input surface, but we did not propagate it prior to
2403fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            // API 20.  Perhaps check for target SDK version.
2404fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0
2405fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            if (info->mData->meta()->findInt64("timeUs", &timestampNs)) {
240647aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar                ALOGV("using buffer PTS of %" PRId64, timestampNs);
2407fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                timestampNs *= 1000;
2408fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar            }
2409fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif
2410fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2411fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mSoftRenderer->render(
2414475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
2415475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    timestampNs, NULL, info->mFormat);
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
24397bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
24407bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
24417bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
244203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
244303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
244403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
244503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
244603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
244703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
244803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
244903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
245003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
245103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
245203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
245303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
24547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2459f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnarstatus_t MediaCodec::handleSetSurface(const sp<Surface> &surface) {
24607541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    status_t err;
24617541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2462f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (mSurface != NULL) {
24637541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_disconnect(
2464f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                mSurface.get(), NATIVE_WINDOW_API_MEDIA);
24657541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24667541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
24677541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
24687541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
24697541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
24707541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2471f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        mSurface.clear();
24727541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
24737541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2474f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (surface != NULL) {
24757541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        err = native_window_api_connect(
2476f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                surface.get(), NATIVE_WINDOW_API_MEDIA);
24777541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24787541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
24797541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            ALOGE("native_window_api_connect returned an error: %s (%d)",
24807541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    strerror(-err), err);
24817541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24827541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            return err;
24837541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
24847541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2485f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        mSurface = surface;
24867541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
24877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
24887541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    return OK;
24897541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
24907541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2491c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2492c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2493c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2494c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2495c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2498c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2499c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2500c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2501c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2502c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2503c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2504c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2505c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2506c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2507c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2508c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2509c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2510c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2511c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2512c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2513c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2514c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2515c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2516c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2517c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2518c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2519c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2520c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2521c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2522c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2523c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2524c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2525c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2526c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2527c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2528c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2529c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2530c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2531c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2532c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2533c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2534c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2535c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2536c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2537749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2538c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2539c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2540c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2541c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2542749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2543749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2544749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2545749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2546749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2547c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2548c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2549c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2550c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2551c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2552c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2553c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2554c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2555c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2556c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2557c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2558c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2559c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2560c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2561c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2562575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2563575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2564575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2565575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2566575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2567e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2568e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2569575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2570e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2571e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2572e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2573575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2574575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2575e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2576e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2577e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2578e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2579e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2580e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2581e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2582e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2583e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2584e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2585575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2586575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2587575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2588575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2589575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2590a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
25911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2592a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2593a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2594a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2595a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2596a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2597a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2598a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2599a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2600a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2601a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2602a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2603a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2604e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2605e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2606e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2607e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2608e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2609e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2610e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2611e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2612e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2613e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2614e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2615e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2616e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2617e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2618e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2619e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2620e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2621e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2622e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2623e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2625e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2626e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2627e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2628a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2629e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2630e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2631e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2632e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2633e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2634e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2636e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2637e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2638e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2639e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2640e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2641e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2642e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2643e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2644e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
26452606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
26462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
26472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
26482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
26502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
26512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
26522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
26532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
26542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
26562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
26572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
26582606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26592606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
26602606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
26612606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
26622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
26632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
26642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
26662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
26672606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
26682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
26695778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2670