MediaCodec.cpp revision b22909302f02bb33ee6264f9a64cd0a4f3790f48
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
84747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
848b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - resource already released");
84947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        return DEAD_OBJECT;
85047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
85147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
852b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (buffer == NULL) {
853b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - null ABuffer");
854b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
855b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
856b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
857b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (format == NULL) {
858b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - null AMessage");
859b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
860b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
861b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
8627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
8637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
864b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
8650e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
866b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - not executing");
8677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
8687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
8697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
873b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
8747bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
875b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (index >= buffers->size()) {
876b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - trying to get buffer with "
877b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage              "bad index (index=%u buffer_size=%u)", index, buffers->size());
878b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
8797bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
880b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
881b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    const BufferInfo &info = buffers->itemAt(index);
882b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (!info.mOwnedByClient) {
883b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - invalid operation "
884b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage              "(index %u is not owned by client)", index);
885b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
886b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
887b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
888b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    // by the time buffers array is initialized, crypto is set
889b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    *buffer = (portIndex == kPortIndexInput && mCrypto != NULL) ?
890b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage                  info.mEncryptedData :
891b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage                  info.mData;
892b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
893b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    *format = info.mFormat;
894b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
8967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
8991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
905496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
9061d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
907496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
908496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
909496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
910496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
911575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
9121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
913575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
914575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
915575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
916575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9195778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
9205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
921c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
929c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9373f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9380e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
940c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
942251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
943251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
944251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9613f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9620e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
96447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INVALID_OPERATION);
965251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
96647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, getStickyError());
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
96847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
97147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
97447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        sp<AMessage> response = new AMessage;
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<ABuffer> &buffer =
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
100947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        response->postReply(replyID);
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10155778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
102392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1025251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1026251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1027251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10299e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
10309e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1031251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1032aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
103352dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1034aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1035aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
10365530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1047c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1048c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1054c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1055c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
1060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10655530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
106603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
1067aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
106803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
106903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
107003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
107103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
107203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
107303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
107403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
107503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
10766e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
10776e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
10786e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
107903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
108003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10869e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
10879e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
10889e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
10899e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
10909e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
10919e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10950e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10985530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1100251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1101575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1104c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1105c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1106251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1111251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1114251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1117c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11235530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1126575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1127c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1132c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1133251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1134251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1135251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1136251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1137251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1138251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1139251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1140251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1142251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1143251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1144c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11495530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
115592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
11565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
115952dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1161717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1163717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
11643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
11663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
116967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    String8 resourceType;
1170717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
11711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
117267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceSecureCodec);
11731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
11741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
117567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                        resourceType = String8(kResourceNonSecureCodec);
11761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
1177c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu
1178c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec;
1179c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                    addResource(resourceType, String8(subtype), 1);
11801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
118592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1187c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                    if (mState == UNINITIALIZED || mState == INITIALIZED) {
1188c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        // In case a kWhatError message came in and replied with error,
1189c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        // we log a warning and ignore.
1190c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        ALOGW("configure interrupted by error, current state %d", mState);
1191c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        break;
1192c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                    }
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11956507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
11966507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
11976507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1198e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1199e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1200e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
12013a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
12023a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
12033a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
12043a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
12062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
121192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
12127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
121392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
12147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
12151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
12167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
12177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
12187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
12197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
12207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
12216507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
12227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
12237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1229d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                case CodecBase::kWhatInputSurfaceAccepted:
1230d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                {
12318f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                    // response to initiateSetInputSurface()
1232d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    status_t err = NO_ERROR;
1233d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    sp<AMessage> response = new AMessage();
1234d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    if (!msg->findInt32("err", &err)) {
1235d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        mHaveInputSurface = true;
1236d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    } else {
1237d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        response->setInt32("err", err);
1238d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    }
1239d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    response->postReply(mReplyID);
1240d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    break;
1241d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                }
1242d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
124392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
12447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
124592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
12461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
12477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
12487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
12497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
12557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
125692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
12587bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1272eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1273eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
127592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
127692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1278eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1280c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1281c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1282c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1283c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1284c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1285c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1286c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1287c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1288c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1289c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1290c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1291eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1293eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1295eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1298c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
1299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                            info.mEncryptedData =
1300c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                                new ABuffer(mem->pointer(), info.mData->capacity());
1301c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1302ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1303ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
13095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
131267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            if (mIsVideo) {
1313c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                String8 subtype;
1314c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                addResource(
1315c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        String8(kResourceGraphicMemory),
1316c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        subtype,
1317c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        getGraphicBufferSize());
131867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            }
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1323575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
132992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("codec output format changed");
13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1333475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1334f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                            mSurface != NULL &&
13353a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(msg->findString("mime", &mime));
13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1339475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1340505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang                            mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mOutputFormat = msg;
1345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1346e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1347e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1348e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1349e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1350e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1351c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1352c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1353e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1354e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1355e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1356e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
13572514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13582514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
13592514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
13608140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
13618140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
13628140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
13638140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
13648140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
13658140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
13668140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
13672514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
13682514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
137290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case CodecBase::kWhatOutputFramesRendered:
137390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
137490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    // ignore these in all states except running, and check that we have a
137590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    // notification set
137690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    if (mState == STARTED && mOnFrameRenderedNotification != NULL) {
137790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        sp<AMessage> notify = mOnFrameRenderedNotification->dup();
137890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        notify->setMessage("data", msg);
137990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        notify->post();
138090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    }
138190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
138290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
138390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
138492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1388c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1389c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1390c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
13968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
13978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
13988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
13998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
14008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
14018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
14028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
14038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
14048ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14058ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
14068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
14088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
14098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
14108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1411251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1412575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1413575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
14158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
14168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
14178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
14188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1419c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
14206e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
14213d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
14223d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
14233d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
14243d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
14253d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
14266e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1427c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1433575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1434575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
143992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1443c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1444c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1445c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14502d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    sp<ABuffer> buffer;
14512d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber                    CHECK(msg->findBuffer("buffer", &buffer));
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1458e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1459e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1460e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1461e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1462e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1463e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1464e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1465e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1466e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1467e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1468e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1469e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1470e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1471e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1472e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1473e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1474c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1475c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1476c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1478c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1479e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1480e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1481c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1482c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1483c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1489575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1490575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1492575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
149692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
150392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1505c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1506c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1507c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1508c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1509c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
15106e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1511c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
151252dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
151467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
151567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
152092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15225530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
15235530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
15245530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
15255530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
15265530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15280e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
15290e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
15300e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
15310e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
15320e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
15330e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
15473f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1551c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
15630db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
15640db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
15745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
158190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case kWhatSetNotification:
158290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
158390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            sp<AMessage> notify;
158490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            if (msg->findMessage("on-frame-rendered", &notify)) {
158590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                mOnFrameRenderedNotification = notify;
158690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            }
158790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            break;
158890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
158990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1590c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1591c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
15923f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1593c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1594c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1595c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1596c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
15970e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
15980e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1599c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1600c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1601c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1602c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1603c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1604c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1605c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1606c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1607c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1608c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1609c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1610c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1611c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1612c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1613c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1614c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1615c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1616c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1617c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1618c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1619c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1620c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1621c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16243f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1628c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
1633f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar            CHECK(msg->findObject("surface", &obj));
16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16388b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            int32_t push;
16398b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
16408b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                mFlags |= kFlagPushBlankBuffersOnShutdown;
16418b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
16428b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
1645f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                status_t err = handleSetSurface(static_cast<Surface *>(obj.get()));
16467541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1647c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
16487541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
16491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
16501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
1651f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                handleSetSurface(NULL);
16521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
16531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16547541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
16557541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
16567541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
16571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
16581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
16591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
16631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1669e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
16738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case kWhatSetSurface:
16791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
16801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
16811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
16821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
16831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            status_t err = OK;
16841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<Surface> surface;
16851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
16861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            switch (mState) {
16871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case CONFIGURED:
16881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case STARTED:
16891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case FLUSHED:
16901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                {
16911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<RefBase> obj;
16921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    (void)msg->findObject("surface", &obj);
16931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<Surface> surface = static_cast<Surface *>(obj.get());
16941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    if (mSurface == NULL) {
16951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support setting surface if it was not set
16961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = INVALID_OPERATION;
16971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else if (obj == NULL) {
16981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support unsetting surface
16991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = BAD_VALUE;
17001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else {
17011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = connectToSurface(surface);
17021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        if (err == BAD_VALUE) {
17031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            // assuming reconnecting to same surface
17041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            // TODO: check if it is the same surface
17051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            err = OK;
17061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        } else {
17071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
17081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                if (mFlags & kFlagUsesSoftwareRenderer) {
17098b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    if (mSoftRenderer != NULL
17108b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                            && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
17118b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                        pushBlankBuffersToNativeWindow(mSurface.get());
17128b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    }
17131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    mSoftRenderer = new SoftwareRenderer(surface);
17141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    // TODO: check if this was successful
17151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                } else {
17161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    err = mCodec->setSurface(surface);
17171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                }
17181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
17191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
17201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                (void)disconnectFromSurface();
17211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                mSurface = surface;
17221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
17231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        }
17241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    }
17251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
17261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
17271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                default:
17291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    err = INVALID_OPERATION;
17301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
17311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
17321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            PostReplyWithError(replyID, err);
17341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
17351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
17361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
17388f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case kWhatSetInputSurface:
17397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
17403f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
17427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
17437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
17447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1745c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
17477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
17487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
17497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
1750d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            if (msg->what() == kWhatCreateInputSurface) {
1751d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->initiateCreateInputSurface();
1752d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            } else {
1753d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                sp<RefBase> obj;
1754d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                CHECK(msg->findObject("input-surface", &obj));
1755d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
17568f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                mCodec->initiateSetInputSurface(
1757d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        static_cast<PersistentSurface *>(obj.get()));
1758d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            }
17597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
17607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17633f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17660e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1767d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
17683d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
17693d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
17703d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
17713d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
17720e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
17730e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1774d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
17750e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1776c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1788c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1789c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1790aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1791aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1792aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
17933f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1794c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1795c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
179647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            // already stopped/released
179747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (mState == UNINITIALIZED && mReleasedByResourceManager) {
179847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                sp<AMessage> response = new AMessage;
179947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->setInt32("err", OK);
180047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->postReply(replyID);
180147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                break;
180247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
180347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
180447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            int32_t reclaimed = 0;
180547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            msg->findInt32("reclaimed", &reclaimed);
180647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (reclaimed) {
180747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                mReleasedByResourceManager = true;
180847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
180947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
181033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
181133223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
18120e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
181333223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
181433223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
181533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
181652dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
181703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
181803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
181903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
182003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
182103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1822c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
182347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
182447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // the previous stop/release completes and then reply with OK.
18256e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
18266e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
18276e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
18286e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
18296e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1831c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1832c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1833c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1834aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1835aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1836aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1837aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
18386e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
18396e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
18406e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1841aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1842aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1843aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1844aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1845c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1846aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1847aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1848aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1849aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
18528b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
18538b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
18548b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                pushBlankBuffersToNativeWindow(mSurface.get());
18558b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18613f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1864c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1865c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1866c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1867c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1868c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1869c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
18706507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
18716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1872c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
18746507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
18756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1884c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
18931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
19055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
19085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
19125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1913c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19223f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1925251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
1926c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
1928251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
1929251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
1930251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1935c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19413f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1944c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1945c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1946c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1947c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1948c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1949c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1958c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
19671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1987c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19963f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1999251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2000c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2002251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2003251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2004251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2009c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
20147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
20153f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
20177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
2018251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2019c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
2021251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2022251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2023251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
20257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
20267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
20277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
20287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
20297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
20307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20333f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2035e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // Unfortunately widevine legacy source requires knowing all of the
2036e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // codec input buffers, so we have to provide them even in async mode.
2037e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            int32_t widevine = 0;
2038e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            msg->findInt32("widevine", &widevine);
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2040e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
2041c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2043251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2044251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2045251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            Vector<sp<ABuffer> > *dstBuffers;
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            for (size_t i = 0; i < srcBuffers.size(); ++i) {
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                const BufferInfo &info = srcBuffers.itemAt(i);
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2060ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                dstBuffers->push_back(
20611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        (portIndex == kPortIndexInput && mCrypto != NULL)
2062ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                                ? info.mEncryptedData : info.mData);
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20713f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2074251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2075c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2077251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2078251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2079251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
20830e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2091e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
2094e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
2095e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
2096e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
20973f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2100e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
21010e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
21020e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
2103e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
2104c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2106251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
2112e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2117496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
2118496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
2119496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
2120496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
2121496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
2122496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2123575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
2124575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
2125575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
2126575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
2127575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2128575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
2129575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
2130575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
2131575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2132717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2133717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
21343f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2135717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2136717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2137717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2138c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2139717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2140717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2141717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2142717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2143717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2144717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2145717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2146717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2147717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2148a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2149a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
21503f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2151a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2152a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2153a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2154a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2155a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2156a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2157a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2158c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2159a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2160a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2161a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21678ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
21688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
21698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
21718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
21728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2173a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
21748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
21758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
21768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
21788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
21798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
21808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2181a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
21828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
21838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
21858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
21868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
21887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
21898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
21918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
21928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    const sp<ABuffer> &codecInputData =
21948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        (mCrypto != NULL) ? info->mEncryptedData : info->mData;
21958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
21968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
21978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
21988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
21998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
22018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
22038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
22058ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
22068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
22078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
22088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
22098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
22108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
22118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
22138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
22148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22155778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
22167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
2221f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        handleSetSurface(NULL);
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2223671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2228e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2229e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
2230c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2231251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2232575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2233575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2234c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2237717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2238671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2239671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2240671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2241aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2242aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2243aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2244aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2245717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2246717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
22502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
22512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22545778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() {
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexInput);
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    returnBuffersToCodecOnPort(kPortIndexOutput);
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22595778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) {
22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
22617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mOwnedByClient = false;
22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
22747fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
22757fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22845778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
22855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2288609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
2289609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
22955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2300475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
2301475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
23254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
23264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
23274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
23284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
23294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
23314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
23324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
23334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
23354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
23364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
23374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
23384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
23404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
23414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
23424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
23434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
23444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
23454b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
23464b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
23474b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
23484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
23504b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
23514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
23524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
23534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
23554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
23564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
23584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
23604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
23614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
23624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
23634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
23644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
23654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->meta()->setInt64("timeUs", timeUs);
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_EOS) {
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("eos", true);
23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (flags & BUFFER_FLAG_CODECCONFIG) {
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mData->meta()->setInt32("csd", true);
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
23931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (size > info->mEncryptedData->capacity()) {
23941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return -ERANGE;
2395ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2396ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
23975b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
23985b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
23995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2400fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
24011bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                (mFlags & kFlagIsSecure) != 0,
24021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
24031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
24041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
2405c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2406c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
24074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
24084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
24095b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                info->mData->base(),
24105b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
24111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2412fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2413fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2414ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2415ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2416fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        info->mData->setRange(0, result);
2417ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
2418ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
24197bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
24207bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
24217bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
24227bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
24237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
24242d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber    reply->setBuffer("buffer", info->mData);
24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24275b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
24285b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
243290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar//static
243390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarsize_t MediaCodec::CreateFramesRenderedMessage(
243490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        std::list<FrameRenderTracker::Info> done, sp<AMessage> &msg) {
243590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    size_t index = 0;
243690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
243790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
243890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
243990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (it->getRenderTimeNs() < 0) {
244090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            continue; // dropped frame from tracking
244190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
244290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->setInt64(AStringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs());
244390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->setInt64(AStringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs());
244490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ++index;
244590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
244690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return index;
244790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
244890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
24495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
24505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
24515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
24525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
24545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
24555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
24565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24580e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
24635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
24737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
24747bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
24757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
24767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
24777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
247879ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
248190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
248290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
248390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
248490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t renderTimeNs = 0;
2485c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar        if (!msg->findInt64("timestampNs", &renderTimeNs)) {
2486c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
2487c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            ALOGV("using buffer PTS of %lld", (long long)mediaTimeUs);
248890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            renderTimeNs = mediaTimeUs * 1000;
2489fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2490c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar        info->mNotify->setInt64("timestampNs", renderTimeNs);
2491fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
249390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            std::list<FrameRenderTracker::Info> doneFrames = mSoftRenderer->render(
2494475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
249590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, renderTimeNs, NULL, info->mFormat);
249690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
249790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            // if we are running, notify rendered frames
249890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            if (!doneFrames.empty() && mState == STARTED && mOnFrameRenderedNotification != NULL) {
249990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                sp<AMessage> notify = mOnFrameRenderedNotification->dup();
250090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                sp<AMessage> data = new AMessage;
250190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                if (CreateFramesRenderedMessage(doneFrames, data)) {
250290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    notify->setMessage("data", data);
250390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    notify->post();
250490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
250590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            }
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify = NULL;
25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
25165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
25297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
25307bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
25317bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
253203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
253303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
253403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
253503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
253603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
253703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
253803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
253903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
254003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
254103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
254203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
254303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
25447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
25501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
25511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface != NULL) {
25521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
25531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err == BAD_VALUE) {
25541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGI("native window already connected. Assuming no change of surface");
2555a81c6229638a4db56752dd77a6610e0f0971e877Lajos Molnar            return err;
2556264bac95912efe121d6a60026612617f04f42966Lajos Molnar        } else if (err == OK) {
2557264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // Require a fresh set of buffers after each connect by using a unique generation
2558264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // number. Rely on the fact that max supported process id by Linux is 2^22.
2559264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // PID is never 0 so we don't have to worry that we use the default generation of 0.
2560264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // TODO: come up with a unique scheme if other producers also set the generation number.
2561264bac95912efe121d6a60026612617f04f42966Lajos Molnar            static uint32_t mSurfaceGeneration = 0;
2562264bac95912efe121d6a60026612617f04f42966Lajos Molnar            uint32_t generation = (getpid() << 10) | (++mSurfaceGeneration & ((1 << 10) - 1));
2563264bac95912efe121d6a60026612617f04f42966Lajos Molnar            surface->setGenerationNumber(generation);
2564264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGI("[%s] setting surface generation to %u", mComponentName.c_str(), generation);
2565264bac95912efe121d6a60026612617f04f42966Lajos Molnar
2566264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // HACK: clear any free buffers. Remove when connect will automatically do this.
2567264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // This is needed as the consumer may be holding onto stale frames that it can reattach
2568264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // to this surface after disconnect/connect, and those free frames would inherit the new
2569264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // generation number. Disconnecting after setting a unique generation prevents this.
2570264bac95912efe121d6a60026612617f04f42966Lajos Molnar            native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2571264bac95912efe121d6a60026612617f04f42966Lajos Molnar            err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2572264bac95912efe121d6a60026612617f04f42966Lajos Molnar        }
2573264bac95912efe121d6a60026612617f04f42966Lajos Molnar
2574264bac95912efe121d6a60026612617f04f42966Lajos Molnar        if (err != OK) {
25751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
25761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
25771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
25781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
25791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
25807541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
25811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::disconnectFromSurface() {
25821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
2583f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (mSurface != NULL) {
2584264bac95912efe121d6a60026612617f04f42966Lajos Molnar        // Resetting generation is not technically needed, but there is no need to keep it either
2585264bac95912efe121d6a60026612617f04f42966Lajos Molnar        mSurface->setGenerationNumber(0);
25861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
25877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
25881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("native_window_api_disconnect returned an error: %s (%d)", strerror(-err), err);
25897541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
25901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // assume disconnected even on error
2591f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        mSurface.clear();
25927541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
25931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
25941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
25957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
25961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::handleSetSurface(const sp<Surface> &surface) {
25971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
25981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mSurface != NULL) {
25991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)disconnectFromSurface();
26001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
2601f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (surface != NULL) {
26021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = connectToSurface(surface);
26031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err == OK) {
26041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mSurface = surface;
26057541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
26067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
26071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
26087541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
26097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2610c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2611c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2612c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2613c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2614c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2615c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2616c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2617c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2618c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2619c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2620c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2621c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2622c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
2623c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        const sp<ABuffer> &buffer =
2624c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2625c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2626c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2627c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2628c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2629c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2630c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2631c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2632c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2633c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2635c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2636c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2637c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2638c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2639c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2640c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2641c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2642c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2643c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2644c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2645c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2646c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2647c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2648c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2649c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2650c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2651c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2652c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2653c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2654c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2655c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2656749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2657c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2658c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2659c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2660c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2661749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2662749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2663749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2664749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2665749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2666c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2667c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2668c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2669c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2670c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2671c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2672c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2673c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2674c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2675c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2676c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2677c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2678c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2679c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2680c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2681575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2682575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2683575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2684575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2685575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2686e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2687e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2688575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2689e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2690e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2691e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2692575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2693575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2694e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2695e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2696e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2697e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2698e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2699e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2700e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2701e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2702e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2703e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2704575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2705575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2706575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2707575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2708575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2709a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
27101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2711a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2712a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2713a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2714a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2715a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2716a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2717a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2718a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2719a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2720a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2721a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2722a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const sp<ABuffer> &buffer) {
2725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2745e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2747a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2748e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2749e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2750e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2751e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
2758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mOutputFormat->setBuffer("csd-0", buffer);
2759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2762e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2763e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
27642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
27652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    if (mState == CONFIGURED && !mBatteryStatNotified) {
27662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
27672606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
27692606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartVideo();
27702606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
27712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStartAudio();
27722606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
27732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27742606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
27752606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
27762606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        BatteryNotifier& notifier(BatteryNotifier::getInstance());
27772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        if (mIsVideo) {
27792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopVideo();
27802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        } else {
27812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang            notifier.noteStopAudio();
27822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        }
27832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
27852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
27862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
27872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
27885778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2789