MediaCodec.cpp revision 4811923e80a8abefa278307ebf8cc9b0294ba67f
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"
224811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim#include "include/SecureBuffer.h"
237e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include "include/SharedMemoryBuffer.h"
245778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/SoftwareRenderer.h"
255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h>
2767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <binder/IPCThreadState.h>
282606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h>
29c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/MemoryDealer.h>
3079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang#include <gui/BufferQueue.h>
311a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
32ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
33d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/IOMX.h>
3467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h>
357e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h>
365778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
395b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
40ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
415778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
446f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
45e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
47744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h>
485778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
49d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXClient.h>
50d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
518b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar#include <media/stagefright/SurfaceUtils.h>
5299e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <mediautils/BatteryNotifier.h>
532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
56e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
575778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
590d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsiehstatic int64_t getId(const sp<IResourceManagerClient> &client) {
6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (int64_t) client.get();
6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) {
6447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    return (err == NO_MEMORY);
6567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2;
684b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wustatic const int kMaxReclaimWaitTimeInUs = 500000;  // 0.5s
6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient {
71090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool reclaimResource() {
7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (codec == NULL) {
7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // codec is already gone.
7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            return true;
7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
7947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        status_t err = codec->reclaim();
804b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        if (err == WOULD_BLOCK) {
814b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            ALOGD("Wait for the client to release codec.");
824b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            usleep(kMaxReclaimWaitTimeInUs);
834b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            ALOGD("Try to reclaim again.");
844b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            err = codec->reclaim(true /* force */);
854b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        }
8667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK) {
8767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
8867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
8967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (err == OK);
9067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
9167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    virtual String8 getName() {
938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        String8 ret;
948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec == NULL) {
968f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            // codec is already gone.
978f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            return ret;
988f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
998f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu
1008f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        AString name;
1018f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec->getName(&name) == OK) {
1028f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            ret.setTo(name.c_str());
1038f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
1048f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        return ret;
1058f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    }
10667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
10767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected:
10867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual ~ResourceManagerClient() {}
10967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
11067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate:
11167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    wp<MediaCodec> mMediaCodec;
11267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
11367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
11467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu};
11567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
11668845c14ebf2c7282800b1abffde38d8e9a57aabRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid)
11768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        : mPid(pid) {
11868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    if (mPid == MediaCodec::kNoPid) {
11968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        mPid = IPCThreadState::self()->getCallingPid();
12068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    }
12167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
12267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
12367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
12467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
12567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
12667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
12767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
12867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
12967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
13067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
13167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
13267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
13367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
13467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
13567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
13667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
137e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu    IInterface::asBinder(mService)->linkToDeath(this);
13867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
13967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
14067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
14167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
14267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
14367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
14467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
14567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
14667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
14767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
1480d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsieh        const sp<IResourceManagerClient> &client,
14967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
15067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
15167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
15267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
15367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
15437c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    mService->addResource(mPid, clientId, client, resources);
15567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
15667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
15867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
15967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
16067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
16167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
16237c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    mService->removeResource(mPid, clientId);
16367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
16467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
16567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
16637c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu        const Vector<MediaResource> &resources) {
16767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
16867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
16967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
17067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
17137c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    return mService->reclaimResource(mPid, resources);
17267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
17367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
1745778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1755778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
1766fc17d1a7c5d2fb117491b2e9f66c6236b526508Lajos Molnar        const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err, pid_t pid) {
17768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    sp<MediaCodec> codec = new MediaCodec(looper, pid);
1785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
179251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
180251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
181251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
182251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
183251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
1845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1865778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
1875778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
1886fc17d1a7c5d2fb117491b2e9f66c6236b526508Lajos Molnar        const sp<ALooper> &looper, const AString &name, status_t *err, pid_t pid) {
18968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    sp<MediaCodec> codec = new MediaCodec(looper, pid);
1905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
191251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
192251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
193251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
194251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
195251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
198d291c222357303b9611cab89d0c3b047584ef377Chong Zhang// static
1995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t MediaCodec::QueryCapabilities(
2005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
2015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps /* nonnull */) {
2025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // TRICKY: this method is used by MediaCodecList/Info during its
2035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // initialization. As such, we cannot create a MediaCodec instance
2045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // because that requires an initialized MediaCodecList.
2055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
2065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecBase> codec = GetCodecBase(name);
2075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (codec == NULL) {
2085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NAME_NOT_FOUND;
2095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
2105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
2115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return codec->queryCapabilities(name, mime, isEncoder, caps);
2125b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
2135b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
2145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar// static
215d291c222357303b9611cab89d0c3b047584ef377Chong Zhangsp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
216d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    OMXClient client;
217addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (client.connect() != OK) {
218addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Failed to connect to OMX to create persistent input surface.");
21979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        return NULL;
22079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    }
22179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
222addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<IOMX> omx = client.interface();
22379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
224d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
225addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<IGraphicBufferSource> bufferSource;
226d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
227addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = omx->createInputSurface(&bufferProducer, &bufferSource);
228d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
229d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
230d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("Failed to create persistent input surface.");
231d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        return NULL;
232d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
233d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
234addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    return new PersistentSurface(bufferProducer, bufferSource);
235d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
236d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
23768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua WuMediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid)
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
23947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu      mReleasedByResourceManager(false),
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
24192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
2427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
244251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
2455778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
246ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
24768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu      mResourceManagerService(new ResourceManagerServiceProxy(pid)),
2482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
2492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
252505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang      mRotationDegrees(0),
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
2555778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
2566507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
2573d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
2583d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
2595778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2615778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
2625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
2675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
2695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
2705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
2725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
2735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
2805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2823f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
28347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    int32_t finalErr = err;
28447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
28547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        // override the err code if MediaCodec has been released by ResourceManager.
28647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        finalErr = DEAD_OBJECT;
28747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
28847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
289c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
29047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    response->setInt32("err", finalErr);
291c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
292c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
293c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2945b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
2955b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarsp<CodecBase> MediaCodec::GetCodecBase(const AString &name, bool nameIsType) {
2965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // at this time only ACodec specifies a mime type.
2975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (nameIsType || name.startsWithIgnoreCase("omx.")) {
2985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return new ACodec;
2995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (name.startsWithIgnoreCase("android.filter.")) {
3005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return new MediaFilter;
3015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else {
3025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NULL;
3035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
3045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
3055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
306dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
30767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
30867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
309671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
310671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
311671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
312671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
313671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
318744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
3195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    mCodec = GetCodecBase(name, nameIsType);
3205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (mCodec == NULL) {
321744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
322744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
323744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
32467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
325dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
32667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
3276f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
3286f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
3296f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
33067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
3316f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
3326f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
33360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
33448a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        if (mcl == NULL) {
33548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            mCodec = NULL;  // remove the codec.
33648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            return NO_INIT; // if called from Java should raise IOException
33748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        }
3386f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
3396f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
34060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
34160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
34260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
34360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
34460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
34567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
34660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
3476f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
3486f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
3496f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
35267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
35367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
3625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this));
3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
37767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
37867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
379ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::Type type =
380ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            secureCodec ? MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
381ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::SubType subtype =
382ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
383ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(type, subtype, 1));
38467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
38567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
38667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
38737c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
38867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
38967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
39067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
39167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
39267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
39367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
39467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
39567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
39667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
39767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
39867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
401c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
4021d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
403c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
404c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
405c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
406c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
407c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
408c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
40990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarstatus_t MediaCodec::setOnFrameRenderedNotification(const sp<AMessage> &notify) {
41090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetNotification, this);
41190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setMessage("on-frame-rendered", notify);
41290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return msg->post();
41390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
41490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
417f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        const sp<Surface> &surface,
4181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
4201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
42267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
42367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
42467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
425505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        if (!format->findInt32("rotation-degrees", &mRotationDegrees)) {
426505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang            mRotationDegrees = 0;
427505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        }
4282034457336d28124e0f9f3c625978052ae03fceaWei Jia
4292034457336d28124e0f9f3c625978052ae03fceaWei Jia        // Prevent possible integer overflow in downstream code.
4302034457336d28124e0f9f3c625978052ae03fceaWei Jia        if (mInitIsEncoder
4312034457336d28124e0f9f3c625978052ae03fceaWei Jia                && (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
4322034457336d28124e0f9f3c625978052ae03fceaWei Jia            ALOGE("buffer size is too big, width=%d, height=%d", mVideoWidth, mVideoHeight);
4332034457336d28124e0f9f3c625978052ae03fceaWei Jia            return BAD_VALUE;
4342034457336d28124e0f9f3c625978052ae03fceaWei Jia        }
43567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
43667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
4385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
439f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    msg->setObject("surface", surface);
4401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
4411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
4421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
4435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
44567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
44667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
447f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
44867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
44967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
450ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::Type type = (mFlags & kFlagIsSecure) ?
451ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
452ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::SubType subtype =
453ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
454ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(type, subtype, 1));
45567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
45667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
457ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
45867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
45967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
46067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
46137c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
46267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
46367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
46467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
465f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
46667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
46767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
46867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
46967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
47067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
47167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
47267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
47367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
47467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
47567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
47667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
47767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
47867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
47967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
48067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
481f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
482f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4858f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangstatus_t MediaCodec::setInputSurface(
486d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
4878f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
488d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface.get());
489d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
490d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> response;
491d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return PostAndAwaitResponse(msg, &response);
492d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
493d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
4941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::setSurface(const sp<Surface> &surface) {
4951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
4961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
4971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
4981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
4991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return PostAndAwaitResponse(msg, &response);
5001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
5011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
5027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
5037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
5041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
5057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
5067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
5077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
5087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
5097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
5107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
5117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
5127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
5137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
5147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
5157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
5167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
5177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
5187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
5197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
5207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
5217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() {
52367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (!mIsVideo) {
52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return 0;
52567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
52667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
52767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    uint64_t size = 0;
52867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
52967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (size_t i = 0; i < portNum; ++i) {
53067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // TODO: this is just an estimation, we should get the real buffer size from ACodec.
53167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
53267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
53367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return size;
53467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
53567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
536ea15fd29af81490311af9e12949b43524c39400eRonghua Wuvoid MediaCodec::addResource(
537ea15fd29af81490311af9e12949b43524c39400eRonghua Wu        MediaResource::Type type, MediaResource::SubType subtype, uint64_t value) {
53867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
539c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(type, subtype, value));
54067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->addResource(
54137c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            getId(mResourceManagerClient), mResourceManagerClient, resources);
54267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
54367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
5445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
5451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
5465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
54767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
54867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
549ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::Type type = (mFlags & kFlagIsSecure) ?
550ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
551ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::SubType subtype =
552ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
553ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(type, subtype, 1));
55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
556ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
55967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
56037c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
56167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
56267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Recover codec from previous error before retry start.
56467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = reset();
56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
56667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to reset codec");
56767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
56867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
56967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            sp<AMessage> response;
57067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = PostAndAwaitResponse(mConfigureMsg, &response);
57167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
57267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to configure codec");
57367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
57467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
57567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
57667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
57867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
58067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
58167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
5871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
5885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
5905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
5915778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5934b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wubool MediaCodec::hasPendingBuffer(int portIndex) {
5944b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu    const Vector<BufferInfo> &buffers = mPortBuffers[portIndex];
5954b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu    for (size_t i = 0; i < buffers.size(); ++i) {
5964b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        const BufferInfo &info = buffers.itemAt(i);
5974b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        if (info.mOwnedByClient) {
5984b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            return true;
5994b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        }
6004b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu    }
6014b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu    return false;
6024b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu}
6034b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
6044b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wubool MediaCodec::hasPendingBuffer() {
6054b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu    return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput);
6064b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu}
6074b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
6084b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wustatus_t MediaCodec::reclaim(bool force) {
60958828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu    ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str());
61047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    sp<AMessage> msg = new AMessage(kWhatRelease, this);
61147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    msg->setInt32("reclaimed", 1);
6124b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu    msg->setInt32("force", force ? 1 : 0);
61347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
61447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    sp<AMessage> response;
6150abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu    status_t ret = PostAndAwaitResponse(msg, &response);
6160abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu    if (ret == -ENOENT) {
6170abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu        ALOGD("MediaCodec looper is gone, skip reclaim");
6180abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu        ret = OK;
6190abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu    }
6200abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu    return ret;
62147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu}
62247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
6241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
628c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
629c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
630671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
631671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
632671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
633671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
634671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
635671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
636671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
637671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
638671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
639671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
640671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
641671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
642671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
643671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
644671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
645671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
646671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
647671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
648671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
649251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
650671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
651671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
652671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
653671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
654671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
655671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
656671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
657671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
658671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
659671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
660dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
661671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
662671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
663671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
664671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
6655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
6665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
6675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
6685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
6695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
6705b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6715b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
6725b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
6735b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
6745b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
6755b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
6761d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
6805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
6825b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
6894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
6904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
6914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
6924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
6934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
6944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
6954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
69618cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker        const CryptoPlugin::Pattern &pattern,
6974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
6985b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
6995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
7005b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
7015b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
7025b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
7035b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
7054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
7064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
7074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
7084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
7094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
7104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
7114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
71218cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker    msg->setInt32("encryptBlocks", pattern.mEncryptBlocks);
71318cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker    msg->setInt32("skipBlocks", pattern.mSkipBlocks);
7144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
7154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
7165b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
7174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
7195b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
7205b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
7215b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
7224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
7234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
7251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
7461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
7651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
773fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
7741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
775fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
776fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
777fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
778fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
779fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
780fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
781fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
782fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
7835778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
7841d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
7921d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
7937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
7957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
7967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
7977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
7991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
8131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
816e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
817e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
818e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
819e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
820e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
821e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
822e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
823e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
824e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
825e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
826717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
8271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
828717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
829717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
830717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
831717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
832717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
833717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
834717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
835717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
836717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
837717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
838717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
839717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
8407e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
841e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
842e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("portIndex", kPortIndexInput);
843e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setPointer("buffers", buffers);
844e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    msg->setInt32("widevine", true);
845e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
846e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    sp<AMessage> response;
847e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar    return PostAndAwaitResponse(msg, &response);
848e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar}
849e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar
8507e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
8511d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8597e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getOutputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
8601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
8635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8665778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8687e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getOutputBuffer(size_t index, sp<MediaCodecBuffer> *buffer) {
8697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
8747e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
8757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
8767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8787e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getInputBuffer(size_t index, sp<MediaCodecBuffer> *buffer) {
8797bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
8807bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
8817bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
8827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
8830e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
8840e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
8850e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
8860e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
8877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
8887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
8897e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        sp<MediaCodecBuffer> *buffer, sp<AMessage> *format) {
8907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
89147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
892b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - resource already released");
89347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        return DEAD_OBJECT;
89447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
89547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
896b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (buffer == NULL) {
8977e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        ALOGE("getBufferAndFormat - null MediaCodecBuffer");
898b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
899b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
900b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
901b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (format == NULL) {
902b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - null AMessage");
903b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
904b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
905b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
9067bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
9077bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
908b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
9090e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
910b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - not executing");
9117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
9127bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
9137bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9147bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
9157bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
9167bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
917b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
9187bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
919b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (index >= buffers->size()) {
920b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - trying to get buffer with "
9210362655ca9494052f348f83dabecf9ea27003976Aaron Vaage              "bad index (index=%zu buffer_size=%zu)", index, buffers->size());
922b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
9237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
924b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
925b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    const BufferInfo &info = buffers->itemAt(index);
926b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (!info.mOwnedByClient) {
927b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - invalid operation "
9280362655ca9494052f348f83dabecf9ea27003976Aaron Vaage              "(the index %zu is not owned by client)", index);
929b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
930b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
931b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
932b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    // by the time buffers array is initialized, crypto is set
9334811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    *buffer = info.mData;
934b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    *format = info.mFormat;
935b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
9367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
9377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
9387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
9395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
9401d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
946496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
9471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
948496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
949496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
950496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
951496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
952575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
9531d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
954575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
955575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
956575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
957575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9605778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
962c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
970c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9783f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
9790e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
981c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
983251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
984251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
985251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
10030e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
100547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INVALID_OPERATION);
1006251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
100747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, getStickyError());
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
100947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
101247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
101547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        sp<AMessage> response = new AMessage;
10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10237e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        const sp<MediaCodecBuffer> &buffer =
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t omxFlags;
10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags = 0;
10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_SYNCFRAME;
10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_CODECCONFIG;
10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (omxFlags & OMX_BUFFERFLAG_EOS) {
10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            flags |= BUFFER_FLAG_EOS;
10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
105047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        response->postReply(replyID);
10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10565778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
106492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatError:
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1066251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1067251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1068251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10709e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
10719e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1072251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1073aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
107452dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1075aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1076aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
10775530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1088c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1089c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1095c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1096c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STOPPING:
1101c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
11025778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // the shutdown complete notification.
11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11065530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
110703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
1108aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
110903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
111003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
111103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
111203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
111303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
111403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
111503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
111603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
11176e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
11186e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
11196e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
112003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
112103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11279e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
11289e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
11299e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
11309e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
11319e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
11329e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11360e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11395530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1142575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
11435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1145c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1146c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1147251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1148251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1149251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1152251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1153251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1154251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1155251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1156251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1157251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1158c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
11645530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1166251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1167575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1168c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1169251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1170251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1171251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1172251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1173c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1174251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1175251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1176251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1177251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1178251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1179251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1180251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1181251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1182251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1183251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1184251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1185c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11905530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1191251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
11955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
119692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentAllocated:
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
120052dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1202717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1204717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
12053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
12073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1210ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                    MediaResource::Type resourceType;
1211717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
12121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
1213ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                        resourceType = MediaResource::kSecureCodec;
12141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
12151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
1216ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                        resourceType = MediaResource::kNonSecureCodec;
12171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
1218c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu
121958828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu                    if (mIsVideo) {
122058828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu                        // audio codec is currently ignored.
1221ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                        addResource(resourceType, MediaResource::kVideoCodec, 1);
122258828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu                    }
12231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
122892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatComponentConfigured:
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1230c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                    if (mState == UNINITIALIZED || mState == INITIALIZED) {
1231c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        // In case a kWhatError message came in and replied with error,
1232c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        // we log a warning and ignore.
1233c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        ALOGW("configure interrupted by error, current state %d", mState);
1234c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        break;
1235c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                    }
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
12396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
12406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1241e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1242e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1243b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    ALOGV("[%s] configured as input format: %s, output format: %s",
1244b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            mComponentName.c_str(),
1245b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            mInputFormat->debugString(4).c_str(),
1246b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            mOutputFormat->debugString(4).c_str());
12473a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
12483a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
12493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
12503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
12513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
12522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
125792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatInputSurfaceCreated:
12587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
125992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
12607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
12611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
12627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
12637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
12647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
1265b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        CHECK(msg->findMessage("input-format", &mInputFormat));
1266b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        CHECK(msg->findMessage("output-format", &mOutputFormat));
1267b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        ALOGV("[%s] input surface created as input format: %s, output format: %s",
1268b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mComponentName.c_str(),
1269b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mInputFormat->debugString(4).c_str(),
1270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mOutputFormat->debugString(4).c_str());
12717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
12727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
12736507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
12747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
12757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
12767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
12777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
12787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
12797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
12807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1281d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                case CodecBase::kWhatInputSurfaceAccepted:
1282d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                {
12838f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                    // response to initiateSetInputSurface()
1284d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    status_t err = NO_ERROR;
1285d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    sp<AMessage> response = new AMessage();
1286d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    if (!msg->findInt32("err", &err)) {
1287addf2cbb120346ae42e78fa739245a353db5edadChong Zhang                        CHECK(msg->findMessage("input-format", &mInputFormat));
1288addf2cbb120346ae42e78fa739245a353db5edadChong Zhang                        CHECK(msg->findMessage("output-format", &mOutputFormat));
1289d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        mHaveInputSurface = true;
1290d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    } else {
1291d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        response->setInt32("err", err);
1292d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    }
1293d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    response->postReply(mReplyID);
1294d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    break;
1295d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                }
1296d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
129792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatSignaledInputEOS:
12987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
129992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
13001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
13017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
13027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
13037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
13047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
13057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
13067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
13077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
13087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
13097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
131092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatBuffersAllocated:
13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
13127bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    Mutex::Autolock al(mBufferLock);
13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t portIndex;
13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("portIndex", &portIndex));
13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGV("%s buffers allocated",
13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                          portIndex == kPortIndexInput ? "input" : "output");
13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(portIndex == kPortIndexInput
13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            || portIndex == kPortIndexOutput);
13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    mPortBuffers[portIndex].clear();
13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1326eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    sp<RefBase> obj;
1327eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    CHECK(msg->findObject("portDesc", &obj));
1328eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber
132992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    sp<CodecBase::PortDescription> portDesc =
133092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                        static_cast<CodecBase::PortDescription *>(obj.get());
13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1332eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    size_t numBuffers = portDesc->countBuffers();
13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1334c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    size_t totalSize = 0;
1335c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    for (size_t i = 0; i < numBuffers; ++i) {
1336c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1337c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            totalSize += portDesc->bufferAt(i)->capacity();
1338c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        }
1339c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1340c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1341c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    if (totalSize) {
1342c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                        mDealer = new MemoryDealer(totalSize, "MediaCodec");
1343c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                    }
1344c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker
1345eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                    for (size_t i = 0; i < numBuffers; ++i) {
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        BufferInfo info;
1347eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mBufferID = portDesc->bufferIDAt(i);
13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        info.mOwnedByClient = false;
1349eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber                        info.mData = portDesc->bufferAt(i);
13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        if (portIndex == kPortIndexInput && mCrypto != NULL) {
1352c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            sp<IMemory> mem = mDealer->allocate(info.mData->capacity());
13534811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            info.mSecureData = info.mData;
13544811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                            info.mData = new SharedMemoryBuffer(mInputFormat, mem);
1355c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                            info.mSharedEncryptedBuffer = mem;
1356ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                        }
1357ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        buffers->push_back(info);
13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    if (portIndex == kPortIndexOutput) {
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        if (mState == STARTING) {
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // We're always allocating output buffers after
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // allocating input buffers, so this is a good
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // indication that now all buffers are allocated.
136667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            if (mIsVideo) {
1367c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                addResource(
1368ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                                        MediaResource::kGraphicMemory,
1369ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                                        MediaResource::kUnspecifiedSubType,
1370c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu                                        getGraphicBufferSize());
137167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                            }
13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(STARTED);
13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            (new AMessage)->postReply(mReplyID);
13745778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        } else {
13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            mFlags |= kFlagOutputBuffersChanged;
1376575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
138292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatOutputFormatChanged:
13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1384b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                    CHECK(msg->findMessage("format", &mOutputFormat));
1385b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar
1386b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    ALOGV("[%s] output format changed to: %s",
1387b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            mComponentName.c_str(), mOutputFormat->debugString(4).c_str());
1388b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
1389475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    if (mSoftRenderer == NULL &&
1390f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                            mSurface != NULL &&
13913a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            (mFlags & kFlagUsesSoftwareRenderer)) {
13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        AString mime;
1393b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar                        CHECK(mOutputFormat->findString("mime", &mime));
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1395b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        // TODO: propagate color aspects to software renderer to allow better
1396b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        // color conversion to RGB. For now, just mark dataspace for YUV
1397b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        // rendering.
1398b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        int32_t dataSpace;
1399b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
1400b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGD("[%s] setting dataspace on output surface to #%x",
1401b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    mComponentName.c_str(), dataSpace);
1402b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            int err = native_window_set_buffers_data_space(
1403b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                    mSurface.get(), (android_dataspace)dataSpace);
1404b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            ALOGW_IF(err != 0, "failed to set dataspace on surface (%d)", err);
1405b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        }
1406b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar
1407475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                        if (mime.startsWithIgnoreCase("video/")) {
1408505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang                            mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagIsEncoder) {
1413e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // Before we announce the format change we should
1414e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // collect codec specific data and amend the output
1415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format as necessary.
1416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagGatherCodecSpecificData;
1417c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagIsAsync) {
1418c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputFormatChanged();
1419e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    } else {
1420e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags |= kFlagOutputFormatChanged;
1421e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        postActivityNotificationIfPossible();
1422e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
14232514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
14242514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    // Notify mCrypto of video resolution changes
14252514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    if (mCrypto != NULL) {
14268140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        int32_t left, top, right, bottom, width, height;
14278140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
14288140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
14298140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        } else if (mOutputFormat->findInt32("width", &width)
14308140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                                && mOutputFormat->findInt32("height", &height)) {
14318140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                            mCrypto->notifyResolution(width, height);
14328140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar                        }
14332514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker                    }
14342514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
143890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                case CodecBase::kWhatOutputFramesRendered:
143990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
144090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    // ignore these in all states except running, and check that we have a
144190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    // notification set
144290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    if (mState == STARTED && mOnFrameRenderedNotification != NULL) {
144390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        sp<AMessage> notify = mOnFrameRenderedNotification->dup();
144490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        notify->setMessage("data", msg);
144590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        notify->post();
144690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    }
144790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
144890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
144990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
145092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFillThisBuffer:
14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
14535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1454c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1455c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1456c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14617e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    // TODO: hold reference of buffer from downstream when
14627e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    // mPortBuffers is removed.
14637e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim
14648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
14658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
14668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
14678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
14698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
14708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
14718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
14728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
14738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
14758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
14768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
14778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
14788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
14798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1480251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1481575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1482575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
14838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
14848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
14858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
14868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
14878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1488c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
14896e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
14903d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
14913d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
14923d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
14933d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
14943d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
14956e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1502575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1503575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
150892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatDrainThisBuffer:
15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1512c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1513c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1514c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15197e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    sp<RefBase> obj;
15207e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    CHECK(msg->findObject("buffer", &obj));
15217e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
15227e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    // TODO: hold buffer's reference when we remove mPortBuffers
15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    int32_t omxFlags;
15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK(msg->findInt32("flags", &omxFlags));
15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    buffer->meta()->setInt32("omxFlags", omxFlags);
15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    if (mFlags & kFlagGatherCodecSpecificData) {
1530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // This is the very first output buffer after a
1531e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // format change was signalled, it'll either contain
1532e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // the one piece of codec specific data we can expect
1533e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        // or there won't be codec specific data.
1534e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
1535e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            status_t err =
1536e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                amendOutputFormatWithCodecSpecificData(buffer);
1537e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1538e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            if (err != OK) {
1539e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                ALOGE("Codec spit out malformed codec "
1540e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                                      "specific data!");
1541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        mFlags &= ~kFlagGatherCodecSpecificData;
1545c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1546c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1547c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1548c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1549c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1552c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1553c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1554c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1560575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1561575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1563575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
156792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatEOS:
15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
15705778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
157492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatShutdownCompleted:
15755778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1576c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == STOPPING) {
1577c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(INITIALIZED);
1578c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    } else {
1579c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        CHECK_EQ(mState, RELEASING);
1580c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        setState(UNINITIALIZED);
15816e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        mComponentName.clear();
1582c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
158352dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
158567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
158667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
159192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                case CodecBase::kWhatFlushCompleted:
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15935530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
15945530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
15955530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
15965530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
15975530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15990e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
16000e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
16010e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
16020e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
16030e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
16040e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16183f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1622c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
16340db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
16350db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
165290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case kWhatSetNotification:
165390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
165490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            sp<AMessage> notify;
165590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            if (msg->findMessage("on-frame-rendered", &notify)) {
165690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                mOnFrameRenderedNotification = notify;
165790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            }
165890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            break;
165990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
166090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1661c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1662c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
16633f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1664c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1665c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1666c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1667c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
16680e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
16690e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1670c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1671c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1672c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1673c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1674c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1675c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1676c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1677c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1678c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1679c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1680c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1681c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1682c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1683c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1684c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1685c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1686c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1687c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1688c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1689c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1690c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1691c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1692c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
16953f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1699c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
1704f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar            CHECK(msg->findObject("surface", &obj));
17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17098b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            int32_t push;
17108b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
17118b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                mFlags |= kFlagPushBlankBuffersOnShutdown;
17128b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
17138b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
1716f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                status_t err = handleSetSurface(static_cast<Surface *>(obj.get()));
17177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1718c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
17197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
17201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
17211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
1722f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                handleSetSurface(NULL);
17231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
17241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
17257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
17267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
17277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
17281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
17291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
17301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
17341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
17448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case kWhatSetSurface:
17501dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
17511dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
17521dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
17531dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            status_t err = OK;
17551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<Surface> surface;
17561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            switch (mState) {
17581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case CONFIGURED:
17591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case STARTED:
17601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case FLUSHED:
17611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                {
17621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<RefBase> obj;
17631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    (void)msg->findObject("surface", &obj);
17641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<Surface> surface = static_cast<Surface *>(obj.get());
17651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    if (mSurface == NULL) {
17661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support setting surface if it was not set
17671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = INVALID_OPERATION;
17681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else if (obj == NULL) {
17691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support unsetting surface
17701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = BAD_VALUE;
17711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else {
17721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = connectToSurface(surface);
1773098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar                        if (err == ALREADY_EXISTS) {
1774098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar                            // reconnecting to same surface
17751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            err = OK;
17761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        } else {
17771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
17781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                if (mFlags & kFlagUsesSoftwareRenderer) {
17798b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    if (mSoftRenderer != NULL
17808b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                            && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
17818b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                        pushBlankBuffersToNativeWindow(mSurface.get());
17828b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    }
17831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    mSoftRenderer = new SoftwareRenderer(surface);
17841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    // TODO: check if this was successful
17851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                } else {
17861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    err = mCodec->setSurface(surface);
17871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                }
17881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
17891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
17901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                (void)disconnectFromSurface();
17911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                mSurface = surface;
17921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
17931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        }
17941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    }
17951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
17961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
17971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
17981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                default:
17991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    err = INVALID_OPERATION;
18001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
18011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
18021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
18031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            PostReplyWithError(replyID, err);
18041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
18051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
18061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
18077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
18088f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case kWhatSetInputSurface:
18097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
18103f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
18127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
18137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
18147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1815c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
18177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
18187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
18197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
1820d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            if (msg->what() == kWhatCreateInputSurface) {
1821d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->initiateCreateInputSurface();
1822d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            } else {
1823d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                sp<RefBase> obj;
1824d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                CHECK(msg->findObject("input-surface", &obj));
1825d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
18268f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                mCodec->initiateSetInputSurface(
1827d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        static_cast<PersistentSurface *>(obj.get()));
1828d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            }
18297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
18307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18333f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18360e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1837d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
18383d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
18393d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
18403d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
18413d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
18420e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
18430e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1844d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
18450e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1846c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1858c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1859c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1860aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1861aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
1862aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
18633f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1864c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
1865c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
186647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            // already stopped/released
186747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (mState == UNINITIALIZED && mReleasedByResourceManager) {
186847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                sp<AMessage> response = new AMessage;
186947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->setInt32("err", OK);
187047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->postReply(replyID);
187147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                break;
187247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
187347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
187447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            int32_t reclaimed = 0;
187547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            msg->findInt32("reclaimed", &reclaimed);
187647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (reclaimed) {
187747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                mReleasedByResourceManager = true;
18784b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
18794b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                int32_t force = 0;
18804b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                msg->findInt32("force", &force);
18814b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                if (!force && hasPendingBuffer()) {
18824b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    ALOGW("Can't reclaim codec right now due to pending buffers.");
18834b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
18844b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    // return WOULD_BLOCK to ask resource manager to retry later.
18854b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    sp<AMessage> response = new AMessage;
18864b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    response->setInt32("err", WOULD_BLOCK);
18874b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    response->postReply(replyID);
18884b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
18894b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    // notify the async client
18904b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    if (mFlags & kFlagIsAsync) {
18914b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                        onError(DEAD_OBJECT, ACTION_CODE_FATAL);
18924b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    }
18934b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    break;
18944b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                }
189547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
189647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
189733223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung            if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1
189833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
18990e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
190033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
190133223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
190233223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
190352dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
190403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
190503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
190603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
190703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
190803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
1909c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
191047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
191147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // the previous stop/release completes and then reply with OK.
19126e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
19136e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
19146e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
19156e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
19166e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1917c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
1918c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
1919c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
1920c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
1921aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
1922aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
1923aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
1924aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
19256e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
19266e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
19276e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
1928aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
1929aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
1930aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
1931aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1932c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
1933aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
1934aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
1935aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
1936aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
1937c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
193886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu            returnBuffersToCodec(reclaimed);
19398b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
19408b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
19418b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                pushBlankBuffersToNativeWindow(mSurface.get());
19428b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19483f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1951c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
1952c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
1953c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1954c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1955c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1956c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
19576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
19586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
1959c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
19616507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
19626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
1971c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
19801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2000c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20093f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2012251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2013c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2015251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2016251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2017251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2022c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20283f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2031c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
2032c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
2033c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2034c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
2035c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
2036c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
20375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
2045c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
20541d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
20565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
20575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
20665778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2074c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
20833f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2086251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2087c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2089251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2090251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2091251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2096c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
21017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
21023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
21047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
21056d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            if (!isExecuting() || !mHaveInputSurface) {
2106c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
2108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
21117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
21127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
21137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
21147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
21157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
21167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
21177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
21203f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2122e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // Unfortunately widevine legacy source requires knowing all of the
2123e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            // codec input buffers, so we have to provide them even in async mode.
2124e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            int32_t widevine = 0;
2125e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            msg->findInt32("widevine", &widevine);
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2127e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar            if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) {
2128c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2132251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21387e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            Vector<sp<MediaCodecBuffer> > *dstBuffers;
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
2142e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang            // If we're using input surface (either non-persistent created by
2143e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang            // createInputSurface(), or persistent set by setInputSurface()),
2144e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang            // give the client an empty input buffers array.
2145e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang            if (portIndex != kPortIndexInput || !mHaveInputSurface) {
2146e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang                const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex];
2147e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang
2148e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang                for (size_t i = 0; i < srcBuffers.size(); ++i) {
2149e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang                    const BufferInfo &info = srcBuffers.itemAt(i);
2150e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang
21514811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                    dstBuffers->push_back(info.mData);
2152e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang                }
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
21613f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2164251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2165c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2167251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2168251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2169251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
21730e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2181e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
2184e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
2185e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
2186e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
21873f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2190e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
21910e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
21920e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
2193e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
2194c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2196251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2197251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2198251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
2202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2207496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
2208496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
2209496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
2210496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
2211496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
2212496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2213575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
2214575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
2215575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
2216575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
2217575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2218575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
2219575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
2220575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
2221575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2222717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2223717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
22243f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2225717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2226717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2227717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2228c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2229717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2230717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2231717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2232717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2233717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2234717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2235717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2236717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2237717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2238a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2239a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
22403f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2241a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2242a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2243a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2244a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2245a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2246a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2247a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2248c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2249a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2250a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2251a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22578ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
22588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
22598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
22618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
22628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2263a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
22648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
22658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
22664f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang        if (csd->size() == 0) {
22674f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang            ALOGW("csd-%zu size is 0", i);
22684f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang        }
22698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
22718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
22728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
22738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2274a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
22758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
22768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
22788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
22798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22807bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    const BufferInfo *info =
22817bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        &mPortBuffers[kPortIndexInput].itemAt(bufferIndex);
22828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
22848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
22858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22864811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    const sp<MediaCodecBuffer> &codecInputData = info->mData;
22878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
22898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
22908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
22918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
22938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
22958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
22961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
22978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
22988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
22998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
23008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
23018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
23028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
23038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
23048ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
23058ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
23068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
23075778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
23087541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
2313f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        handleSetSurface(NULL);
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2315671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagGatherCodecSpecificData;
2322c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2323251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2324575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2325575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2326c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2329717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2330671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2331671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2332671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2333aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2334aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2335aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2336aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2337717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2338717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
23422606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
23432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
234686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wuvoid MediaCodec::returnBuffersToCodec(bool isReclaim) {
234786b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    returnBuffersToCodecOnPort(kPortIndexInput, isReclaim);
234886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    returnBuffersToCodecOnPort(kPortIndexOutput, isReclaim);
23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
235186b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wuvoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim) {
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
23537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mNotify != NULL) {
23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> msg = info->mNotify;
23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            info->mNotify = NULL;
236386b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu            if (isReclaim && info->mOwnedByClient) {
236486b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu                ALOGD("port %d buffer %zu still owned by client when codec is reclaimed",
236586b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu                        portIndex, i);
236686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu            } else {
23674811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim                // TODO: clear memory reference.
236886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu                info->mOwnedByClient = false;
236986b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu            }
23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (portIndex == kPortIndexInput) {
23727fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                /* no error, just returning buffers */
23737fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar                msg->setInt32("err", OK);
23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            msg->post();
23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23825778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2386609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    uint32_t bufferID;
2387609b815a3131d22da38b2f452faa9f89daad4039Andy Hung    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    for (size_t i = 0; i < buffers->size(); ++i) {
23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        BufferInfo *info = &buffers->editItemAt(i);
23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (info->mBufferID == bufferID) {
23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(info->mNotify == NULL);
23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("reply", &info->mNotify));
23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2398475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            info->mFormat =
2399475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat;
24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mAvailPortBuffers[portIndex].push_back(i);
24015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return i;
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    TRESPASS();
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return 0;
24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
24234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
24244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
24254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
24264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
24274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
24294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
24304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
2431d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker    CryptoPlugin::Pattern pattern;
24324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
24344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
24354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
24364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
24374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
24394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
24404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
24414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
2442d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker            pattern.mEncryptBlocks = 0;
2443d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker            pattern.mSkipBlocks = 0;
24444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
24454b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
24464b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
24474b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
24484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
24494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24504b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
24514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
24524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
24534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
2454d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker        CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
2455d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker        CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
24564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
24584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
24594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
24614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
24634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
24644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
24654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
24664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
24674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
24684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index);
24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> reply = info->mNotify;
24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24864811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    sp<MediaCodecBuffer> buffer = info->mData;
24871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
24885b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
24895b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
24905b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
24914811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        void *dst_pointer = nullptr;
24929ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker        ICrypto::DestinationType dst_type = ICrypto::kDestinationTypeOpaqueHandle;
24939ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker
24944811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        if ((mFlags & kFlagIsSecure) == 0) {
24954811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim            dst_pointer = info->mSecureData->base();
24969ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker            dst_type = ICrypto::kDestinationTypeVmPointer;
24974811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        } else {
24984811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim            sp<SecureBuffer> secureData = static_cast<SecureBuffer *>(info->mSecureData.get());
24994811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim            dst_pointer = secureData->getDestinationPointer();
25004811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim            dst_type = secureData->getDestinationType();
25019ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker        }
25029ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker
2503fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = mCrypto->decrypt(
25049ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker                dst_type,
25051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
25061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
25071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
250818cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker                pattern,
2509c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                info->mSharedEncryptedBuffer,
2510c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker                offset,
25114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
25124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
2513a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar                dst_pointer,
25145b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
25151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
2516fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (result < 0) {
2517fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            return result;
2518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
2519ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
25204811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        info->mSecureData->setRange(0, result);
25214811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        buffer = info->mSecureData;
25224811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    }
25234811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    buffer->meta()->setInt64("timeUs", timeUs);
25244811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim
25254811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    if (flags & BUFFER_FLAG_EOS) {
25264811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        buffer->meta()->setInt32("eos", true);
25274811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    }
25284811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim
25294811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    if (flags & BUFFER_FLAG_CODECCONFIG) {
25304811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim        buffer->meta()->setInt32("csd", true);
2531ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
25327e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    // TODO: release buffer reference.
2533ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
25347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
25357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
25367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
25377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
25387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
25394811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    reply->setObject("buffer", buffer);
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    reply->post();
25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25425b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    info->mNotify = NULL;
25435b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
254790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar//static
254890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarsize_t MediaCodec::CreateFramesRenderedMessage(
25490d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsieh        const std::list<FrameRenderTracker::Info> &done, sp<AMessage> &msg) {
255090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    size_t index = 0;
255190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
255290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
255390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
255490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (it->getRenderTimeNs() < 0) {
255590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            continue; // dropped frame from tracking
255690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
255790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->setInt64(AStringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs());
255890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->setInt64(AStringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs());
255990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ++index;
256090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
256190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return index;
256290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
256390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
25645778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
25695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
25705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
25715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25730e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
25745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
25755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
25785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
25795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index);
25825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (info->mNotify == NULL || !info->mOwnedByClient) {
25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
25887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
25897bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
25907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
25917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
25927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
259379ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou    if (render && info->mData != NULL && info->mData->size() != 0) {
25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        info->mNotify->setInt32("render", true);
25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
259690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
259790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info->mData->meta()->findInt64("timeUs", &mediaTimeUs);
259890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
259990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t renderTimeNs = 0;
2600c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar        if (!msg->findInt64("timestampNs", &renderTimeNs)) {
2601c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
2602c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            ALOGV("using buffer PTS of %lld", (long long)mediaTimeUs);
260390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            renderTimeNs = mediaTimeUs * 1000;
2604fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2605c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar        info->mNotify->setInt64("timestampNs", renderTimeNs);
2606fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
260890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            std::list<FrameRenderTracker::Info> doneFrames = mSoftRenderer->render(
2609475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                    info->mData->data(), info->mData->size(),
261090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    mediaTimeUs, renderTimeNs, NULL, info->mFormat);
261190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
261290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            // if we are running, notify rendered frames
261390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            if (!doneFrames.empty() && mState == STARTED && mOnFrameRenderedNotification != NULL) {
261490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                sp<AMessage> notify = mOnFrameRenderedNotification->dup();
261590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                sp<AMessage> data = new AMessage;
261690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                if (CreateFramesRenderedMessage(doneFrames, data)) {
261790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    notify->setMessage("data", data);
261890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    notify->post();
261990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
262090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            }
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
26225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26247e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    info->mNotify->setObject("buffer", info->mData);
26257e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    // TODO: release buffer reference.
26265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mNotify->post();
26277e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    info->mNotify.clear();
26285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
26305778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26325778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
26335778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
26345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
26365778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
26385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index);
26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
26467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
26477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
26487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
264903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
265003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
265103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        if (info->mFormat != NULL) {
265203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
265303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findBuffer("image-data", &imageData)) {
265403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
265503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
265603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
265703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) {
265803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
265903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
266003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
26617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
26625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
26645778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
26671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
26681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface != NULL) {
2669b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar        uint64_t oldId, newId;
2670098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        if (mSurface != NULL
2671b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar                && surface->getUniqueId(&newId) == NO_ERROR
2672b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar                && mSurface->getUniqueId(&oldId) == NO_ERROR
2673b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar                && newId == oldId) {
2674b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar            ALOGI("[%s] connecting to the same surface. Nothing to do.", mComponentName.c_str());
2675098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            return ALREADY_EXISTS;
2676098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        }
2677098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar
26781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2679098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        if (err == OK) {
2680264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // Require a fresh set of buffers after each connect by using a unique generation
2681264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // number. Rely on the fact that max supported process id by Linux is 2^22.
2682264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // PID is never 0 so we don't have to worry that we use the default generation of 0.
2683264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // TODO: come up with a unique scheme if other producers also set the generation number.
2684264bac95912efe121d6a60026612617f04f42966Lajos Molnar            static uint32_t mSurfaceGeneration = 0;
2685264bac95912efe121d6a60026612617f04f42966Lajos Molnar            uint32_t generation = (getpid() << 10) | (++mSurfaceGeneration & ((1 << 10) - 1));
2686264bac95912efe121d6a60026612617f04f42966Lajos Molnar            surface->setGenerationNumber(generation);
2687264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGI("[%s] setting surface generation to %u", mComponentName.c_str(), generation);
2688264bac95912efe121d6a60026612617f04f42966Lajos Molnar
2689264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // HACK: clear any free buffers. Remove when connect will automatically do this.
2690264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // This is needed as the consumer may be holding onto stale frames that it can reattach
2691264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // to this surface after disconnect/connect, and those free frames would inherit the new
2692264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // generation number. Disconnecting after setting a unique generation prevents this.
2693264bac95912efe121d6a60026612617f04f42966Lajos Molnar            native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2694264bac95912efe121d6a60026612617f04f42966Lajos Molnar            err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2695264bac95912efe121d6a60026612617f04f42966Lajos Molnar        }
2696264bac95912efe121d6a60026612617f04f42966Lajos Molnar
2697264bac95912efe121d6a60026612617f04f42966Lajos Molnar        if (err != OK) {
26981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
26991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
27001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
2701098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    // do not return ALREADY_EXISTS unless surfaces are the same
2702098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    return err == ALREADY_EXISTS ? BAD_VALUE : err;
27031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
27047541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
27051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::disconnectFromSurface() {
27061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
2707f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (mSurface != NULL) {
2708264bac95912efe121d6a60026612617f04f42966Lajos Molnar        // Resetting generation is not technically needed, but there is no need to keep it either
2709264bac95912efe121d6a60026612617f04f42966Lajos Molnar        mSurface->setGenerationNumber(0);
27101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
27117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
27121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("native_window_api_disconnect returned an error: %s (%d)", strerror(-err), err);
27137541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
27141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // assume disconnected even on error
2715f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        mSurface.clear();
27167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
27171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
27181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
27197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
27201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::handleSetSurface(const sp<Surface> &surface) {
27211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
27221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mSurface != NULL) {
27231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)disconnectFromSurface();
27241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
2725f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (surface != NULL) {
27261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = connectToSurface(surface);
27271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err == OK) {
27281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mSurface = surface;
27297541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
27307541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
27311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
27327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
27337541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2734c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2735c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2736c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2737c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2738c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2739c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2740c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2741c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2742c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2743c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2744c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2745c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2746c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
27477e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        const sp<MediaCodecBuffer> &buffer =
2748c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mPortBuffers[kPortIndexOutput].itemAt(index).mData;
2749c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2750c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2751c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2752c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2753c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2754c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2755c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2756c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2757c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2758c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2759c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2760c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int32_t omxFlags;
2761c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags));
2762c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2763c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        uint32_t flags = 0;
2764c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
2765c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_SYNCFRAME;
2766c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2767c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
2768c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_CODECCONFIG;
2769c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2770c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        if (omxFlags & OMX_BUFFERFLAG_EOS) {
2771c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            flags |= BUFFER_FLAG_EOS;
2772c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
2773c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2774c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2775c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2776c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2777c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2778c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2779c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2780749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2781c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2782c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2783c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2784c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2785749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2786749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2787749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2788749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2789749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2790c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2791c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2792c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2793c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2794c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2795c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2796c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2797c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2798c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2799c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2800c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2801c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2802c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2803c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2804c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2805575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2806575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2807575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2808575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2809575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2810e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2811e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2812575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2813e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2814e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2815e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2816575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2817575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2818e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2819e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2820e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2821e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2822e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2823e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2824e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2825e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2826e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2827e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2828575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2829575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2830575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2831575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2832575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2833a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
28341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2835a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2836a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2837a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2838a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2839a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2840a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2841a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2842a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2843a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2844a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2845a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2846a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2847e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
28487e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        const sp<MediaCodecBuffer> &buffer) {
2849e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2850e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2851e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2852e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2853e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2854e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2855e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2856e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2857e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2858e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2859e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2860e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2861e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2862e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2863e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2865e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2866e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2867e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2868e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2869e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2870e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2871a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2877e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2878e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2879e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2881e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
28827e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        sp<ABuffer> csd = new ABuffer(buffer->size());
28837e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        memcpy(csd->data(), buffer->data(), buffer->size());
28847e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        csd->setRange(0, buffer->size());
28857e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        mOutputFormat->setBuffer("csd-0", csd);
2886e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2887e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2888e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2889e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2890e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
28912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
28923f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    if (!mIsVideo) {
28933f273d10817ddb2f792ae043de692efcdf1988aeWei Jia        return;
28943f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    }
28952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
28963f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    if (mState == CONFIGURED && !mBatteryStatNotified) {
28973f273d10817ddb2f792ae043de692efcdf1988aeWei Jia        BatteryNotifier::getInstance().noteStartVideo();
28982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
28992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
29003f273d10817ddb2f792ae043de692efcdf1988aeWei Jia        BatteryNotifier::getInstance().noteStopVideo();
29012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
29022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
29032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
29042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
29055778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
2906