MediaCodec.cpp revision 68845c14ebf2c7282800b1abffde38d8e9a57aab
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
24c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h>
2567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <binder/IPCThreadState.h>
262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h>
27c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/MemoryDealer.h>
2879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang#include <gui/BufferQueue.h>
291a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
30ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
31d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/IOMX.h>
3267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h>
335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
365b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
37ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
402606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
416f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
42e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
435778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
44744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h>
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
46d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXClient.h>
47d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXCodec.h>
48d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
498b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar#include <media/stagefright/SurfaceUtils.h>
5099e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <mediautils/BatteryNotifier.h>
512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
54e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
555778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic int64_t getId(sp<IResourceManagerClient> client) {
5867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (int64_t) client.get();
5967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) {
6247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    return (err == NO_MEMORY);
6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2;
6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient {
6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool reclaimResource() {
7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (codec == NULL) {
7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // codec is already gone.
7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            return true;
7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
7647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        status_t err = codec->reclaim();
7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK) {
7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
7967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (err == OK);
8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
8267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
838f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    virtual String8 getName() {
848f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        String8 ret;
858f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
868f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec == NULL) {
878f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            // codec is already gone.
888f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            return ret;
898f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
908f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu
918f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        AString name;
928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec->getName(&name) == OK) {
938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            ret.setTo(name.c_str());
948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        return ret;
968f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    }
9767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
9867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected:
9967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual ~ResourceManagerClient() {}
10067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate:
10267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    wp<MediaCodec> mMediaCodec;
10367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
10567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu};
10667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid)
10868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        : mPid(pid) {
10968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    if (mPid == MediaCodec::kNoPid) {
11068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        mPid = IPCThreadState::self()->getCallingPid();
11168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    }
11267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
11367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
11467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
11567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
11667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
11767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
11867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
11967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
12067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
12167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
12267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
12367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
12467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
12567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
12667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
12767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
128e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu    IInterface::asBinder(mService)->linkToDeath(this);
12967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
13067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
13167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
13267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
13367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
13467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
13567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
13667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
13767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
13867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
13967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const sp<IResourceManagerClient> client,
14067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
14167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
14267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
14367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
14467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
14537c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    mService->addResource(mPid, clientId, client, resources);
14667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
14767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
14867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
14967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
15067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
15167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
15267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
15337c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    mService->removeResource(mPid, clientId);
15467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
15567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
15737c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu        const Vector<MediaResource> &resources) {
15867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
15967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
16067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
16167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
16237c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    return mService->reclaimResource(mPid, resources);
16367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
16467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
1655778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1665778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
16768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err, pid_t pid) {
16868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    sp<MediaCodec> codec = new MediaCodec(looper, pid);
1695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
170251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
171251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
172251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
173251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
174251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1775778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1785778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
17968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        const sp<ALooper> &looper, const char *name, status_t *err, pid_t pid) {
18068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    sp<MediaCodec> codec = new MediaCodec(looper, pid);
1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
182251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
183251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
184251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
185251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
186251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
1875778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
189d291c222357303b9611cab89d0c3b047584ef377Chong Zhang// static
190d291c222357303b9611cab89d0c3b047584ef377Chong Zhangsp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
191d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    OMXClient client;
192d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    CHECK_EQ(client.connect(), (status_t)OK);
193d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IOMX> omx = client.interface();
194d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
19579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    const sp<IMediaCodecList> mediaCodecList = MediaCodecList::getInstance();
19679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    if (mediaCodecList == NULL) {
19779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        ALOGE("Failed to obtain MediaCodecList!");
19879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        return NULL; // if called from Java should raise IOException
19979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    }
20079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
20179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    AString tmp;
20279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    sp<AMessage> globalSettings = mediaCodecList->getGlobalSettings();
20379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    if (globalSettings == NULL || !globalSettings->findString(
20479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang            kMaxEncoderInputBuffers, &tmp)) {
20579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        ALOGE("Failed to get encoder input buffer count!");
20679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        return NULL;
20779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    }
20879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
20979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    int32_t bufferCount = strtol(tmp.c_str(), NULL, 10);
21079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    if (bufferCount <= 0
21179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang            || bufferCount > BufferQueue::MAX_MAX_ACQUIRED_BUFFERS) {
21279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        ALOGE("Encoder input buffer count is invalid!");
21379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        return NULL;
21479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    }
21579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
216d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
217d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferConsumer> bufferConsumer;
218d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
219d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    status_t err = omx->createPersistentInputSurface(
220d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            &bufferProducer, &bufferConsumer);
221d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
222d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
223d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("Failed to create persistent input surface.");
224d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        return NULL;
225d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
226d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
22779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    err = bufferConsumer->setMaxAcquiredBufferCount(bufferCount);
22879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
22979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    if (err != NO_ERROR) {
23079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
23179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang                bufferCount, err);
23279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        return NULL;
23379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    }
23479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
235d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return new PersistentSurface(bufferProducer, bufferConsumer);
236d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
237d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
23868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua WuMediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid)
2395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
24047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu      mReleasedByResourceManager(false),
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
24292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
2437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
245251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
2465778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
247ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
24868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu      mResourceManagerService(new ResourceManagerServiceProxy(pid)),
2492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
2502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
253505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang      mRotationDegrees(0),
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
2576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
2583d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
2593d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2625778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2833f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
28447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    int32_t finalErr = err;
28547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
28647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        // override the err code if MediaCodec has been released by ResourceManager.
28747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        finalErr = DEAD_OBJECT;
28847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
28947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
290c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
29147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    response->setInt32("err", finalErr);
292c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
293c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
294c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
295dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
29667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
29767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
298671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
299671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
300671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
301671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
302671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
307744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
308bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung    if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) {
309744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new ACodec;
310744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else if (!nameIsType
311bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung            && !strncasecmp(name.c_str(), "android.filter.", 15)) {
312744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        mCodec = new MediaFilter;
313744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    } else {
314744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
315744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
316744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
31767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
318dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
31967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
3206f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
3216f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
3226f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
32367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
3246f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
3256f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
32660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
32748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        if (mcl == NULL) {
32848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            mCodec = NULL;  // remove the codec.
32948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            return NO_INIT; // if called from Java should raise IOException
33048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        }
3316f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
3326f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
33360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
33460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
33560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
33660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
33760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
33867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
33960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
3406f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
3416f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
3426f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
34567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
34667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
37167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
37267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec;
373c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
374c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
37567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
37667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
37767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
37837c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
37967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
38067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
38167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
38267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
38367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
38467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
38567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
38667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
38767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
38867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
38967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
3905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
392c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
3931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
394c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
395c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
396c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
397c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
398c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
399c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
40090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarstatus_t MediaCodec::setOnFrameRenderedNotification(const sp<AMessage> &notify) {
40190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetNotification, this);
40290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setMessage("on-frame-rendered", notify);
40390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return msg->post();
40490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
40590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
4065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
408f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        const sp<Surface> &surface,
4091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
4111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
41367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
41467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
41567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
416505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        if (!format->findInt32("rotation-degrees", &mRotationDegrees)) {
417505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang            mRotationDegrees = 0;
418505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        }
41967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
42067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
423f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    msg->setObject("surface", surface);
4241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
4251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
4261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
43067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
431f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
43267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
43367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
43467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
43567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
436c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
437c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
43867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
43967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
44067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
44167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
44267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
44437c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
44567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
44667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
44767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
448f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
44967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
45067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
45167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
45267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
45367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
45467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
45567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
45667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
45767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
45867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
45967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
46067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
46167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
46267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
46367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
464f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
465f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4688f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangstatus_t MediaCodec::setInputSurface(
469d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
4708f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
471d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface.get());
472d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
473d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> response;
474d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return PostAndAwaitResponse(msg, &response);
475d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
476d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
4771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::setSurface(const sp<Surface> &surface) {
4781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
4791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
4801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
4821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return PostAndAwaitResponse(msg, &response);
4831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
4841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
4867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
4871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
4887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
4897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
4907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
4917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
4927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
4937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
4947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
4957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
4967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
4977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
4987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
4997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
5007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
5017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
5027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
5037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() {
50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (!mIsVideo) {
50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return 0;
50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
50967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
51067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    uint64_t size = 0;
51167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
51267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (size_t i = 0; i < portNum; ++i) {
51367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // TODO: this is just an estimation, we should get the real buffer size from ACodec.
51467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
51567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
51667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return size;
51767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
51867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
519c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wuvoid MediaCodec::addResource(const String8 &type, const String8 &subtype, uint64_t value) {
52067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
521c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(type, subtype, value));
52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->addResource(
52337c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            getId(mResourceManagerClient), mResourceManagerClient, resources);
52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
52567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
5271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
52967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
53067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
53167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    const char *type = (mFlags & kFlagIsSecure) ?
53267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            kResourceSecureCodec : kResourceNonSecureCodec;
533c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
534c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(String8(type), String8(subtype), 1));
53567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
53667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
53767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1));
53867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
53967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
54067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
54137c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
54267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
54367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
54467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Recover codec from previous error before retry start.
54567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = reset();
54667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
54767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to reset codec");
54867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
54967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            sp<AMessage> response;
55167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = PostAndAwaitResponse(mConfigureMsg, &response);
55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
55367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to configure codec");
55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
55667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
55967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
56067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
56167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
56267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
56467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
5655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
5681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wustatus_t MediaCodec::reclaim() {
57547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    sp<AMessage> msg = new AMessage(kWhatRelease, this);
57647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    msg->setInt32("reclaimed", 1);
57747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
57847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    sp<AMessage> response;
57947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    return PostAndAwaitResponse(msg, &response);
58047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu}
58147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
582c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
5831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
584c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
585c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
586c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
587c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
588c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
589671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
590671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
591671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
592671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
593671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
594671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
595671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
596671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
597671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
598671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
599671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
600671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
601671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
602671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
603671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
604671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
605671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
606671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
607671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
608251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
609671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
610671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
611671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
612671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
613671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
614671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
615671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
616671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
617671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
618671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
619dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
620671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
621671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
622671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
623671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
6245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
6275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
6285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
6295b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6305b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6315b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6325b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6335b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
6345b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
6365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
6375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
6385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
6395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
6405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
6415b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
6425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6474b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
6484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
6494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
6504b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
6514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
6524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
6534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
6544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
6554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
6565b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6575b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6585b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6595b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6605b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
6615b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
6634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
6644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
6654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
6664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
6674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
6684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
6694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
6704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
6714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
6725b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
6734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
6744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
6755b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
6765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
6784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
6794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
6805778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
6811d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
6885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
6935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
6965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
6975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
6985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
6995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
7015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
7021d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
7035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
7135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
7211d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
729fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
7301d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
731fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
732fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
733fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
734fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
735fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
736fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
737fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
738fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
7401d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
7481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
7497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
7517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
7527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
7537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
7551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
768e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
7691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
770e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
771e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
772e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
773e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
774e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
775e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
776e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
777e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
778e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
779e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
780e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
781e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
782717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
7831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
784717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
785717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
786717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
787717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
788717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
789717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
790717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
791717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
792717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
793717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
794717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
795717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
796e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const {
797e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
798e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("portIndex", kPortIndexInput);
799e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setPointer("buffers", buffers);
800e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("widevine", true);
801e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
802e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> response;
803e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    return PostAndAwaitResponse(msg, &response);
804e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar}
805e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
8071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const {
8161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
8185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8225778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8247bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) {
8257bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8267bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
8277bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8287bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
8307bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<ABuffer> buffer;
8317bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
8327bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8337bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) {
8357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
8377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8390e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
8400e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
8410e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
8420e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
8437bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
8447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
8457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        sp<ABuffer> *buffer, sp<AMessage> *format) {
8467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
8477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
84847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
84947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        return DEAD_OBJECT;
85047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
85147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
8527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
8537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
8540e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
8557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
8567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
8577bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8587bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
8597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
8607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
8617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
8627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    if (index < buffers->size()) {
8637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        const BufferInfo &info = buffers->itemAt(index);
8647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        if (info.mOwnedByClient) {
8650837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            // by the time buffers array is initialized, crypto is set
8660837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            if (portIndex == kPortIndexInput && mCrypto != NULL) {
8670837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mEncryptedData;
8680837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            } else {
8690837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar                *buffer = info.mData;
8700837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar            }
8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar            *format = info.mFormat;
8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        }
8737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
8747bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
8757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8775778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
8781d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
884496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
8851d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
886496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
887496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
888496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
889496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
890575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
8911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
892575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
893575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
894575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
895575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
8965778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8985778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
900c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
908c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
9095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9163f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9170e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
919c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
921251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
922251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
923251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9403f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9410e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
94347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INVALID_OPERATION);
944251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
94547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, getStickyError());
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
94747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
95047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
95347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        sp<AMessage> response = new AMessage;
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
98847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        response->postReply(replyID);
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9945778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
100292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1004251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1005251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1006251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10089e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
10099e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1010251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1011aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
101252dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1013aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1014aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
10155530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1026c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1027c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1033c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1034c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
1039c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10445530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
104503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
1046aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
104703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
104803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
104903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
105003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
105103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
105203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
105303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
105403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
10556e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
10566e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
10576e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
105803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
105903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10659e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
10669e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
10679e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
10689e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
10699e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
10709e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10775530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1079251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1080575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1083c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1084c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1085251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1086251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1087251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1088251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1089251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1090251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1091251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1092251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1093251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1094251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1095251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1096c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11025530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1104251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1105575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1106c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1111c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1114251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1117251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1123c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11285530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
113492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
113852dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
11395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1140717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
11415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1142717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
11433a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
11453a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
114867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    String8 resourceType;
1149717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
11501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
115167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceSecureCodec);
11521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
11531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
115467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceNonSecureCodec);
11551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
1156c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu
1157c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
1158c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    addResource(resourceType, String8(subtype), 1);
11591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
116492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1166c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                    if (mState == UNINITIALIZED || mState == INITIALIZED) {
1167c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        // In case a kWhatError message came in and replied with error,
1168c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        // we log a warning and ignore.
1169c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        ALOGW("configure interrupted by error, current state %d", mState);
1170c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        break;
1171c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                    }
11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
11756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
11766507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1177e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1178e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1179e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
11803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
11813a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
11823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
11833a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
11843a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
11852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
119092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
11917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
119292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
11937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
11941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
11957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
11967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
11977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
11987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
11997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
12006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
12017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
12027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1208d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                case CodecBase::kWhatInputSurfaceAccepted:
1209d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                {
12108f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                    // response to initiateSetInputSurface()
1211d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    status_t err = NO_ERROR;
1212d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    sp<AMessage> response = new AMessage();
1213d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    if (!msg->findInt32("err", &err)) {
1214d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        mHaveInputSurface = true;
1215d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    } else {
1216d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        response->setInt32("err", err);
1217d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    }
1218d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    response->postReply(mReplyID);
1219d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    break;
1220d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                }
1221d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
122292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
12237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
122492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
12251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
12267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
12277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
12287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
123592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1251eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1252eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1253eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
125492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
125592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1257eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1259c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1260c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1261c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1262c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1263c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1264c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1265c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1266c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1267c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1268c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1269c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1272eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1277c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1278ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
1279c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                                new ABuffer(mem->pointer(), info.mData->capacity());
1280c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1281ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
129167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            if (mIsVideo) {
1292c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                String8 subtype;
1293c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                addResource(
1294c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        String8(kResourceGraphicMemory),
1295c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        subtype,
1296c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        getGraphicBufferSize());
129767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            }
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1302575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
130892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1312475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1313f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                            mSurface != NULL &&
13143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1318475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1319505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang                            mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
1324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1325e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1326e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1327e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1328e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1329e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1330c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1331c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1332e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1333e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1334e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1335e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
13362514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13372514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
13382514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
13398140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
13408140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
13418140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
13428140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
13438140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
13448140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
13458140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
13462514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
13472514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
135190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case CodecBase::kWhatOutputFramesRendered:
135290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
135390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    // ignore these in all states except running, and check that we have a
135490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    // notification set
135590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    if (mState == STARTED && mOnFrameRenderedNotification != NULL) {
135690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        sp<AMessage> notify = mOnFrameRenderedNotification->dup();
135790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        notify->setMessage("data", msg);
135890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        notify->post();
135990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    }
136090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
136190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
136290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
136392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1367c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1368c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1369c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
13758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
13768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
13778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
13798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
13808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
13818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
13828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
13838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
13858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
13878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
13888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
13898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1390251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1391575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1392575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
13938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
13948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
13958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
13968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
13978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1398c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
13996e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
14003d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
14013d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
14023d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
14033d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
14043d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
14056e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1406c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1412575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1413575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
141892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1422c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1423c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1424c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14292d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
14302d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
14345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1449e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1458e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1459e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
14665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1468575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1469575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1471575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
147592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
148292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1484c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1485c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1486c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1487c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1488c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
14896e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1490c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
149152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
149367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
149467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
149992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15015530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
15025530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
15035530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
15045530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
15055530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
15080e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
15090e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
15100e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
15110e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
15120e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15263f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1530c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
15420db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
15430db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
156090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case kWhatSetNotification:
156190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
156290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            sp<AMessage> notify;
156390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            if (msg->findMessage("on-frame-rendered", &notify)) {
156490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                mOnFrameRenderedNotification = notify;
156590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            }
156690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            break;
156790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
156890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1570c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
15713f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1572c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1573c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1574c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1575c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
15760e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
15770e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1578c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1579c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1580c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1581c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1582c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1583c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1584c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1585c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1586c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1587c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1588c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1589c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1590c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1591c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1592c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1593c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1594c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1595c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1596c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1597c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1598c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1599c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1600c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16033f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1607c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
1612f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar            CHECK(msg->findObject("surface", &obj));
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16178b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            int32_t push;
16188b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
16198b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                mFlags |= kFlagPushBlankBuffersOnShutdown;
16208b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
16218b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
1624f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                status_t err = handleSetSurface(static_cast<Surface *>(obj.get()));
16257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1626c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
16277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
16281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
16291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
1630f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                handleSetSurface(NULL);
16311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
16321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16337541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
16347541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
16357541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
16371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
16381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
16421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1648e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
16528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case kWhatSetSurface:
16581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
16591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
16601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
16611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
16621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            status_t err = OK;
16631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<Surface> surface;
16641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
16651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            switch (mState) {
16661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case CONFIGURED:
16671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case STARTED:
16681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case FLUSHED:
16691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                {
16701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<RefBase> obj;
16711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    (void)msg->findObject("surface", &obj);
16721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<Surface> surface = static_cast<Surface *>(obj.get());
16731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    if (mSurface == NULL) {
16741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support setting surface if it was not set
16751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = INVALID_OPERATION;
16761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else if (obj == NULL) {
16771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support unsetting surface
16781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = BAD_VALUE;
16791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else {
16801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = connectToSurface(surface);
16811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        if (err == BAD_VALUE) {
16821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            // assuming reconnecting to same surface
16831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            // TODO: check if it is the same surface
16841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            err = OK;
16851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        } else {
16861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
16871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                if (mFlags & kFlagUsesSoftwareRenderer) {
16888b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    if (mSoftRenderer != NULL
16898b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                            && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
16908b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                        pushBlankBuffersToNativeWindow(mSurface.get());
16918b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    }
16921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    mSoftRenderer = new SoftwareRenderer(surface);
16931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    // TODO: check if this was successful
16941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                } else {
16951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    err = mCodec->setSurface(surface);
16961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                }
16971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
16981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
16991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                (void)disconnectFromSurface();
17001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                mSurface = surface;
17011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
17021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        }
17031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    }
17041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
17051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
17061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                default:
17081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    err = INVALID_OPERATION;
17091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
17101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
17111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            PostReplyWithError(replyID, err);
17131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
17141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
17151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
17178f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case kWhatSetInputSurface:
17187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
17193f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
17217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
17227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
17237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1724c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
17267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
17277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
17287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
1729d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            if (msg->what() == kWhatCreateInputSurface) {
1730d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->initiateCreateInputSurface();
1731d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            } else {
1732d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                sp<RefBase> obj;
1733d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                CHECK(msg->findObject("input-surface", &obj));
1734d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
17358f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                mCodec->initiateSetInputSurface(
1736d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        static_cast<PersistentSurface *>(obj.get()));
1737d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            }
17387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
17397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
17405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17423f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17450e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1746d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
17473d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
17483d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
17493d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
17503d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
17510e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
17520e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1753d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
17540e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1755c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1767c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1768c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1769aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1770aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1771aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
17723f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1773c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1774c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
177547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            // already stopped/released
177647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (mState == UNINITIALIZED && mReleasedByResourceManager) {
177747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                sp<AMessage> response = new AMessage;
177847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->setInt32("err", OK);
177947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->postReply(replyID);
178047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                break;
178147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
178247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
178347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            int32_t reclaimed = 0;
178447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            msg->findInt32("reclaimed", &reclaimed);
178547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (reclaimed) {
178647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                mReleasedByResourceManager = true;
178747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
178847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
178933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
179033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
17910e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
179233223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
179333223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
179433223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
179552dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
179603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
179703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
179803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
179903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
180003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1801c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
180247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
180347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // the previous stop/release completes and then reply with OK.
18046e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
18056e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
18066e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
18076e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
18086e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1809c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1810c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1811c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1812c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1813aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1814aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1815aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1816aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
18176e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
18186e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
18196e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1820aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1821aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1822aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1823aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1824c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1825aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1826aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1827aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1828aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
18318b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
18328b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
18338b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                pushBlankBuffersToNativeWindow(mSurface.get());
18348b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18403f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1843c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1844c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1845c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1846c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1847c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1848c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
18496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
18506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1851c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
18536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
18546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1863c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
18721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1892c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
18935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19013f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1904251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1905c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1907251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1908251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1909251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1914c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19203f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1923c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1924c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1925c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1926c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1927c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1928c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1937c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
19461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1966c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1978251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1979c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1981251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1982251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1983251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1988c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
19937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
19943f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
19967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1997251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1998c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
2000251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2001251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2002251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
20047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
20057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
20067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
20077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
20087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
20097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20123f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2014e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // Unfortunately widevine legacy source requires knowing all of the
2015e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // codec input buffers, so we have to provide them even in async mode.
2016e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            int32_t widevine = 0;
2017e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            msg->findInt32("widevine", &widevine);
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2019e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
2020c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2022251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2023251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2024251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2039ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
20401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
2041ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20503f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2053251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2054c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2056251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2057251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2058251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
20620e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2070e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
2073e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
2074e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
2075e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
20763f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2079e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
20800e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
20810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
2082e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
2083c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2085251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2086251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2087251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
2091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2096496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
2097496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
2098496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
2099496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
2100496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
2101496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2102575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
2103575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
2104575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
2105575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
2106575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2107575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
2108575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
2109575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
2110575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2111717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2112717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
21133f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2114717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2115717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2116717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2117c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2118717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2119717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2120717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2121717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2122717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2123717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2124717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2125717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2126717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2127a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2128a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
21293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2130a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2131a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2132a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2133a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2134a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2135a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2136a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2137c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2138a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2139a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2140a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21468ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
21478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
21488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
21508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
21518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2152a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
21538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
21548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
21558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
21578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
21588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
21598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2160a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
21618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
21628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
21648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
21658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
21677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
21688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
21708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
21718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
21738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
21748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
21768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
21778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
21788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
21808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
21828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
21848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
21858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
21868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
21878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
21888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
21898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
21908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
21928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
21938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21945778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
21957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
2200f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        handleSetSurface(NULL);
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2202671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2207e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2208e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
2209c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2210251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2211575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2212575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2213c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2216717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2217671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2218671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2219671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2220aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2221aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2222aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2223aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2224717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2225717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
22292606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
22302606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22335778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22385778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
22407bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
22537fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
22547fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2267609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
2268609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2279475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
2280475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
22845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
23005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
23044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
23054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
23064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
23074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
23084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
23104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
23114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
23124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
23144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
23154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
23164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
23174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
23194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
23204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
23214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
23224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
23234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
23244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
23254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
23264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
23274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
23294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
23304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
23314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
23324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
23344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
23354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
23374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
23394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
23404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
23414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
23424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
23434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
23444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
23721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
23731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
2374ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2375ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
23765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
23775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
23785b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2379fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
23801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
23811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
23821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
23831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
2384c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2385c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
23864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
23874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
23885b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
23895b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
23901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2391fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2392fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2393ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2394ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2395fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
2396ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2397ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
23987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
23997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
24007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
24017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
24027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
24032d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24065b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
24075b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
241190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar//static
241290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarsize_t MediaCodec::CreateFramesRenderedMessage(
241390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        std::list<FrameRenderTracker::Info> done, sp<AMessage> &msg) {
241490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    size_t index = 0;
241590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
241690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
241790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
241890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (it->getRenderTimeNs() < 0) {
241990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            continue; // dropped frame from tracking
242090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
242190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->setInt64(AStringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs());
242290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->setInt64(AStringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs());
242390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ++index;
242490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
242590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return index;
242690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
242790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
24285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24370e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
24425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
24435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
24465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
24485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
24527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
24537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
24547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
24557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
24567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
245779ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
24585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
246090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
246190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
246290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
246390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t renderTimeNs = 0;
2464c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar        if (!msg->findInt64("timestampNs", &renderTimeNs)) {
2465c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
2466c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            ALOGV("using buffer PTS of %lld", (long long)mediaTimeUs);
246790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            renderTimeNs = mediaTimeUs * 1000;
2468fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2469c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar        info->mNotify->setInt64("timestampNs", renderTimeNs);
2470fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
247290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            std::list<FrameRenderTracker::Info> doneFrames = mSoftRenderer->render(
2473475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
247490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, renderTimeNs, NULL, info->mFormat);
247590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
247690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            // if we are running, notify rendered frames
247790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            if (!doneFrames.empty() && mState == STARTED && mOnFrameRenderedNotification != NULL) {
247890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                sp<AMessage> notify = mOnFrameRenderedNotification->dup();
247990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                sp<AMessage> data = new AMessage;
248090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                if (CreateFramesRenderedMessage(doneFrames, data)) {
248190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    notify->setMessage("data", data);
248290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    notify->post();
248390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
248490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            }
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
25087bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
25097bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
25107bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
251103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
251203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
251303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
251403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
251503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
251603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
251703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
251803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
251903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
252003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
252103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
252203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
25237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
25291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
25301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface != NULL) {
25311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
25321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err == BAD_VALUE) {
25331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGI("native window already connected. Assuming no change of surface");
2534a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            return err;
2535264bac95912efe121d6a60026612617f04f42966Lajos Molnar        } else if (err == OK) {
2536264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // Require a fresh set of buffers after each connect by using a unique generation
2537264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // number. Rely on the fact that max supported process id by Linux is 2^22.
2538264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // PID is never 0 so we don't have to worry that we use the default generation of 0.
2539264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // TODO: come up with a unique scheme if other producers also set the generation number.
2540264bac95912efe121d6a60026612617f04f42966Lajos Molnar            static uint32_t mSurfaceGeneration = 0;
2541264bac95912efe121d6a60026612617f04f42966Lajos Molnar            uint32_t generation = (getpid() << 10) | (++mSurfaceGeneration & ((1 << 10) - 1));
2542264bac95912efe121d6a60026612617f04f42966Lajos Molnar            surface->setGenerationNumber(generation);
2543264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGI("[%s] setting surface generation to %u", mComponentName.c_str(), generation);
2544264bac95912efe121d6a60026612617f04f42966Lajos Molnar
2545264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // HACK: clear any free buffers. Remove when connect will automatically do this.
2546264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // This is needed as the consumer may be holding onto stale frames that it can reattach
2547264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // to this surface after disconnect/connect, and those free frames would inherit the new
2548264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // generation number. Disconnecting after setting a unique generation prevents this.
2549264bac95912efe121d6a60026612617f04f42966Lajos Molnar            native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2550264bac95912efe121d6a60026612617f04f42966Lajos Molnar            err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2551264bac95912efe121d6a60026612617f04f42966Lajos Molnar        }
2552264bac95912efe121d6a60026612617f04f42966Lajos Molnar
2553264bac95912efe121d6a60026612617f04f42966Lajos Molnar        if (err != OK) {
25541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
25551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
25561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
25571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
25581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
25597541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
25601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::disconnectFromSurface() {
25611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
2562f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (mSurface != NULL) {
2563264bac95912efe121d6a60026612617f04f42966Lajos Molnar        // Resetting generation is not technically needed, but there is no need to keep it either
2564264bac95912efe121d6a60026612617f04f42966Lajos Molnar        mSurface->setGenerationNumber(0);
25651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
25667541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
25671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("native_window_api_disconnect returned an error: %s (%d)", strerror(-err), err);
25687541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
25691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // assume disconnected even on error
2570f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        mSurface.clear();
25717541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
25721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
25731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
25747541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
25751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::handleSetSurface(const sp<Surface> &surface) {
25761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
25771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mSurface != NULL) {
25781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)disconnectFromSurface();
25791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
2580f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (surface != NULL) {
25811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = connectToSurface(surface);
25821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err == OK) {
25831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mSurface = surface;
25847541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
25857541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
25861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
25877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
25887541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2589c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2590c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2591c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2592c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2593c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2594c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2595c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2596c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2597c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2598c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2599c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2600c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2601c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2602c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2603c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2604c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2605c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2606c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2607c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2608c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2609c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2610c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2611c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2612c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2613c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2614c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2615c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2616c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2617c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2618c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2619c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2620c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2621c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2622c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2623c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2624c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2625c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2626c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2627c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2628c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2629c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2630c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2631c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2632c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2633c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2635749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2636c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2637c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2638c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2639c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2640749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2641749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2642749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2643749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2644749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2645c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2646c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2647c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2648c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2649c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2650c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2651c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2652c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2653c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2654c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2655c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2656c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2657c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2658c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2659c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2660575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2661575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2662575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2663575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2664575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2665e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2666e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2667575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2668e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2669e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2670e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2671575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2672575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2673e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2674e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2675e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2676e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2677e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2678e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2679e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2680e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2681e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2682e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2683575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2684575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2685575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2686575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2687575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2688a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
26891d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2690a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2691a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2692a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2693a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2694a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2695a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2696a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2697a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2698a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2699a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2700a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2701a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2702e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2703e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2704e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2705e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2706e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2707e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2708e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2709e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2711e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2712e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2713e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2714e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2715e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2716e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2717e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2718e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2719e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2720e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2726a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
27432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
27442606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
27452606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
27462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
27482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
27492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
27502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
27512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
27522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
27542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
27552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
27562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
27582606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
27592606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
27602606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
27612606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
27622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
27642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
27652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
27662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27675778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2768