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
269dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang#include <android/media/IDescrambler.h>
27c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h>
2867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <binder/IPCThreadState.h>
292606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h>
30c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/MemoryDealer.h>
3179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang#include <gui/BufferQueue.h>
321a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h>
33ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
34d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/IOMX.h>
3567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h>
367e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim#include <media/MediaCodecBuffer.h>
37db1221479a7ffe7094c51c463bbd36522ed106abRay Essick#include <media/MediaAnalyticsItem.h>
385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h>
395778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h>
405778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h>
415b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
42dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/foundation/AUtils.h>
43ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
445778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
476f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
48e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
50744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h>
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
52d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXClient.h>
53d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
548b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar#include <media/stagefright/SurfaceUtils.h>
5599e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <mediautils/BatteryNotifier.h>
562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
582606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
59e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
605778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
62db1221479a7ffe7094c51c463bbd36522ed106abRay Essick// key for media statistics
638574195df5de20af5fc16d6f9da1b132d6d5bfeeRay Essickstatic const char *kCodecKeyName = "codec";
64db1221479a7ffe7094c51c463bbd36522ed106abRay Essick// attrs for media statistics
65afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecCodec = "android.media.mediacodec.codec";  /* e.g. OMX.google.aac.decoder */
66afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecMime = "android.media.mediacodec.mime";    /* e.g. audio/mime */
67afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecMode = "android.media.mediacodec.mode";    /* audio, video */
68afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecSecure = "android.media.mediacodec.secure";   /* 0, 1 */
69afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecHeight = "android.media.mediacodec.height";   /* 0..n */
70afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecWidth = "android.media.mediacodec.width";     /* 0..n */
71afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecRotation = "android.media.mediacodec.rotation-degrees";  /* 0/90/180/270 */
72afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecCrypto = "android.media.mediacodec.crypto";   /* 0,1 */
73afb43f76821e6a63e17e6484289a40430ada6978Ray Essickstatic const char *kCodecEncoder = "android.media.mediacodec.encoder"; /* 0,1 */
748574195df5de20af5fc16d6f9da1b132d6d5bfeeRay Essick
75db1221479a7ffe7094c51c463bbd36522ed106abRay Essick
76db1221479a7ffe7094c51c463bbd36522ed106abRay Essick
770d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsiehstatic int64_t getId(const sp<IResourceManagerClient> &client) {
7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (int64_t) client.get();
7967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) {
8247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    return (err == NO_MEMORY);
8367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
8467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
8567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2;
864b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wustatic const int kMaxReclaimWaitTimeInUs = 500000;  // 0.5s
87dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic const int kNumBuffersAlign = 16;
8867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
8979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim////////////////////////////////////////////////////////////////////////////////
9079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
9167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient {
92090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
9367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
9467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool reclaimResource() {
9567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
9667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (codec == NULL) {
9767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // codec is already gone.
9867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            return true;
9967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
10047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        status_t err = codec->reclaim();
1014b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        if (err == WOULD_BLOCK) {
1024b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            ALOGD("Wait for the client to release codec.");
1034b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            usleep(kMaxReclaimWaitTimeInUs);
1044b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            ALOGD("Try to reclaim again.");
1054b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            err = codec->reclaim(true /* force */);
1064b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        }
10767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK) {
10867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
10967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
11067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (err == OK);
11167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
11267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
1138f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    virtual String8 getName() {
1148f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        String8 ret;
1158f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
1168f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec == NULL) {
1178f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            // codec is already gone.
1188f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            return ret;
1198f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
1208f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu
1218f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        AString name;
1228f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec->getName(&name) == OK) {
1238f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            ret.setTo(name.c_str());
1248f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
1258f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        return ret;
1268f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    }
12767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
12867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected:
12967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual ~ResourceManagerClient() {}
13067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
13167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate:
13267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    wp<MediaCodec> mMediaCodec;
13367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
13467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
13567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu};
13667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
13768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid)
13868845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        : mPid(pid) {
13968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    if (mPid == MediaCodec::kNoPid) {
14068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        mPid = IPCThreadState::self()->getCallingPid();
14168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    }
14267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
14367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
14467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
14567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
14667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
14767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
14867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
14967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
15167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
15267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
15367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
15467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
15567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
15667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
15767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
158e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu    IInterface::asBinder(mService)->linkToDeath(this);
15967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
16067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
16167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
16267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
16367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
16467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
16567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
16667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
16767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
16867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
1690d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsieh        const sp<IResourceManagerClient> &client,
17067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
17167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
17267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
17367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
17467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
17537c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    mService->addResource(mPid, clientId, client, resources);
17667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
17767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
17867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
17967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
18067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
18167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
18267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
18337c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    mService->removeResource(mPid, clientId);
18467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
18567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
18667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
18737c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu        const Vector<MediaResource> &resources) {
18867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
18967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
19067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
19167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
19237c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    return mService->reclaimResource(mPid, resources);
19367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
19467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
19579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim////////////////////////////////////////////////////////////////////////////////
19679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
197dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimMediaCodec::BufferInfo::BufferInfo() : mOwnedByClient(false) {}
198dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
199dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim////////////////////////////////////////////////////////////////////////////////
200dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
20179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimnamespace {
20279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
20379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimenum {
20479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatFillThisBuffer      = 'fill',
20579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatDrainThisBuffer     = 'drai',
20679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatEOS                 = 'eos ',
207dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    kWhatStartCompleted      = 'Scom',
20879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatStopCompleted       = 'scom',
20979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatReleaseCompleted    = 'rcom',
21079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatFlushCompleted      = 'fcom',
21179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatError               = 'erro',
21279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatComponentAllocated  = 'cAll',
21379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatComponentConfigured = 'cCon',
21479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatInputSurfaceCreated = 'isfc',
21579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatInputSurfaceAccepted = 'isfa',
21679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatSignaledInputEOS    = 'seos',
21779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatOutputFramesRendered = 'outR',
218dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    kWhatOutputBuffersChanged = 'outC',
21979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim};
22079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
221dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimclass BufferCallback : public CodecBase::BufferCallback {
22279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimpublic:
223dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    explicit BufferCallback(const sp<AMessage> &notify);
224dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual ~BufferCallback() = default;
225dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
226dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual void onInputBufferAvailable(
227dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            size_t index, const sp<MediaCodecBuffer> &buffer) override;
228dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual void onOutputBufferAvailable(
229dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            size_t index, const sp<MediaCodecBuffer> &buffer) override;
230dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimprivate:
231dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    const sp<AMessage> mNotify;
232dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim};
233dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
234dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimBufferCallback::BufferCallback(const sp<AMessage> &notify)
235dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    : mNotify(notify) {}
236dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
237dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid BufferCallback::onInputBufferAvailable(
238dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        size_t index, const sp<MediaCodecBuffer> &buffer) {
239dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    sp<AMessage> notify(mNotify->dup());
240dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatFillThisBuffer);
241dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setSize("index", index);
242dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setObject("buffer", buffer);
243dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->post();
244dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
245dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
246dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid BufferCallback::onOutputBufferAvailable(
247dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        size_t index, const sp<MediaCodecBuffer> &buffer) {
248dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    sp<AMessage> notify(mNotify->dup());
249dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatDrainThisBuffer);
250dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setSize("index", index);
251dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setObject("buffer", buffer);
252dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->post();
253dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
254dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
255dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimclass CodecCallback : public CodecBase::CodecCallback {
256dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimpublic:
257dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    explicit CodecCallback(const sp<AMessage> &notify);
258dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual ~CodecCallback() = default;
25979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
26079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onEos(status_t err) override;
261dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual void onStartCompleted() override;
26279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onStopCompleted() override;
26379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onReleaseCompleted() override;
26479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onFlushCompleted() override;
26579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onError(status_t err, enum ActionCode actionCode) override;
26679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onComponentAllocated(const char *componentName) override;
26779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onComponentConfigured(
26879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) override;
26979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onInputSurfaceCreated(
27079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &inputFormat,
27179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &outputFormat,
27279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<BufferProducerWrapper> &inputSurface) override;
27379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onInputSurfaceCreationFailed(status_t err) override;
27479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onInputSurfaceAccepted(
27579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &inputFormat,
27679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &outputFormat) override;
27779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onInputSurfaceDeclined(status_t err) override;
27879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onSignaledInputEOS(status_t err) override;
27979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onOutputFramesRendered(const std::list<FrameRenderTracker::Info> &done) override;
280dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual void onOutputBuffersChanged() override;
28179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimprivate:
28279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    const sp<AMessage> mNotify;
28379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim};
28479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
285dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimCodecCallback::CodecCallback(const sp<AMessage> &notify) : mNotify(notify) {}
28679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
287dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onEos(status_t err) {
28879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
289dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatEOS);
290dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("err", err);
291fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim    notify->post();
292fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim}
293fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim
294dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onStartCompleted() {
295fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim    sp<AMessage> notify(mNotify->dup());
296dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatStartCompleted);
29779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
29879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
29979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
300dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onStopCompleted() {
30179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
30279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatStopCompleted);
30379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
30479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
30579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
306dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onReleaseCompleted() {
30779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
30879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatReleaseCompleted);
30979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
31079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
31179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
312dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onFlushCompleted() {
31379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
31479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatFlushCompleted);
31579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
31679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
31779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
318dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onError(status_t err, enum ActionCode actionCode) {
31979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
32079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatError);
32179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("err", err);
32279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("actionCode", actionCode);
32379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
32479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
32579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
326dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onComponentAllocated(const char *componentName) {
32779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
32879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatComponentAllocated);
32979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setString("componentName", componentName);
33079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
33179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
33279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
333dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onComponentConfigured(
33479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
33579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
33679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatComponentConfigured);
33779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("input-format", inputFormat);
33879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("output-format", outputFormat);
33979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
34079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
34179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
342dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onInputSurfaceCreated(
34379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &inputFormat,
34479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &outputFormat,
34579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<BufferProducerWrapper> &inputSurface) {
34679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
34779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatInputSurfaceCreated);
34879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("input-format", inputFormat);
34979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("output-format", outputFormat);
35079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setObject("input-surface", inputSurface);
35179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
35279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
35379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
354dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onInputSurfaceCreationFailed(status_t err) {
35579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
35679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatInputSurfaceCreated);
35779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("err", err);
35879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
35979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
36079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
361dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onInputSurfaceAccepted(
36279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &inputFormat,
36379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &outputFormat) {
36479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
36579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatInputSurfaceAccepted);
36679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("input-format", inputFormat);
36779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("output-format", outputFormat);
36879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
36979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
37079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
371dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onInputSurfaceDeclined(status_t err) {
37279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
37379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatInputSurfaceAccepted);
37479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("err", err);
37579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
37679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
37779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
378dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onSignaledInputEOS(status_t err) {
37979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
38079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatSignaledInputEOS);
38179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    if (err != OK) {
38279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        notify->setInt32("err", err);
38379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    }
38479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
38579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
38679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
387dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onOutputFramesRendered(const std::list<FrameRenderTracker::Info> &done) {
38879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
38979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatOutputFramesRendered);
39079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    if (MediaCodec::CreateFramesRenderedMessage(done, notify)) {
39179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        notify->post();
39279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    }
39379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
39479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
395dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onOutputBuffersChanged() {
396dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    sp<AMessage> notify(mNotify->dup());
397dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatOutputBuffersChanged);
398dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->post();
399dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
400dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
40179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}  // namespace
40279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
40379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim////////////////////////////////////////////////////////////////////////////////
40479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
4065778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
407f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err, pid_t pid,
408f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        uid_t uid) {
409f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    sp<MediaCodec> codec = new MediaCodec(looper, pid, uid);
4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
411251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
412251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
413251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
414251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
415251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
4195778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
420f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        const sp<ALooper> &looper, const AString &name, status_t *err, pid_t pid, uid_t uid) {
421f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    sp<MediaCodec> codec = new MediaCodec(looper, pid, uid);
4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
423251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
424251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
425251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
426251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
427251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
430d291c222357303b9611cab89d0c3b047584ef377Chong Zhang// static
4315b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t MediaCodec::QueryCapabilities(
4325b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
4335b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps /* nonnull */) {
4345b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // TRICKY: this method is used by MediaCodecList/Info during its
4355b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // initialization. As such, we cannot create a MediaCodec instance
4365b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // because that requires an initialized MediaCodecList.
4375b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
4385b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecBase> codec = GetCodecBase(name);
4395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (codec == NULL) {
4405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NAME_NOT_FOUND;
4415b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
4425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
4435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return codec->queryCapabilities(name, mime, isEncoder, caps);
4445b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
4455b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
4465b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar// static
447d291c222357303b9611cab89d0c3b047584ef377Chong Zhangsp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
448d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    OMXClient client;
449addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (client.connect() != OK) {
450addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Failed to connect to OMX to create persistent input surface.");
45179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        return NULL;
45279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    }
45379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
454addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<IOMX> omx = client.interface();
45579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
456d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
457addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<IGraphicBufferSource> bufferSource;
458d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
459addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = omx->createInputSurface(&bufferProducer, &bufferSource);
460d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
461d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
462d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("Failed to create persistent input surface.");
463d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        return NULL;
464d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
465d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
466addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    return new PersistentSurface(bufferProducer, bufferSource);
467d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
468d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
469f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei JiaMediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
47147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu      mReleasedByResourceManager(false),
4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
47392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
4747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
4755778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
476251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
4775778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
478ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
47968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu      mResourceManagerService(new ResourceManagerServiceProxy(pid)),
4802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
4812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
48267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
48367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
484505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang      mRotationDegrees(0),
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
4886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
4893d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
4903d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
491f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    if (uid == kNoUid) {
492f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        mUid = IPCThreadState::self()->getCallingUid();
493f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    } else {
494f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        mUid = uid;
495f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    }
496db1221479a7ffe7094c51c463bbd36522ed106abRay Essick    // set up our new record, get a sessionID, put it into the in-progress list
4978574195df5de20af5fc16d6f9da1b132d6d5bfeeRay Essick    mAnalyticsItem = new MediaAnalyticsItem(kCodecKeyName);
498db1221479a7ffe7094c51c463bbd36522ed106abRay Essick    if (mAnalyticsItem != NULL) {
499db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        (void) mAnalyticsItem->generateSessionID();
500db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        // don't record it yet; only at the end, when we have decided that we have
501db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        // data worth writing (e.g. .count() > 0)
502db1221479a7ffe7094c51c463bbd36522ed106abRay Essick    }
5035778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5055778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
508db1221479a7ffe7094c51c463bbd36522ed106abRay Essick
509db1221479a7ffe7094c51c463bbd36522ed106abRay Essick    if (mAnalyticsItem != NULL ) {
510db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        if (mAnalyticsItem->count() > 0) {
511db1221479a7ffe7094c51c463bbd36522ed106abRay Essick            mAnalyticsItem->setFinalized(true);
512db1221479a7ffe7094c51c463bbd36522ed106abRay Essick            mAnalyticsItem->selfrecord();
513db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        }
514db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        delete mAnalyticsItem;
515db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        mAnalyticsItem = NULL;
516db1221479a7ffe7094c51c463bbd36522ed106abRay Essick    }
5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5195778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
5205778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
5215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
5225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
5235778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
5255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
5265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
5295778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
5335778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5353f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
53647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    int32_t finalErr = err;
53747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
53847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        // override the err code if MediaCodec has been released by ResourceManager.
53947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        finalErr = DEAD_OBJECT;
54047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
54147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
542c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
54347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    response->setInt32("err", finalErr);
544c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
545c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
546c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
5475b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
5485b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarsp<CodecBase> MediaCodec::GetCodecBase(const AString &name, bool nameIsType) {
5495b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // at this time only ACodec specifies a mime type.
5505b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (nameIsType || name.startsWithIgnoreCase("omx.")) {
5515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return new ACodec;
5525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (name.startsWithIgnoreCase("android.filter.")) {
5535b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return new MediaFilter;
5545b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else {
5555b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NULL;
5565b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
5575b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
5585b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
559dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
56067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
56167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
562671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
563671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
564671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
565671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
566671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
5675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
5685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
571744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
5725b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    mCodec = GetCodecBase(name, nameIsType);
5735b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (mCodec == NULL) {
574744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
575744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
576744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
578dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
5806f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
5816f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
5826f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
5846f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
5856f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
58660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
58748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        if (mcl == NULL) {
58848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            mCodec = NULL;  // remove the codec.
58948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            return NO_INIT; // if called from Java should raise IOException
59048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        }
5916f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
5926f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
59360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
59460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
59560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
59660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
59760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
59960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
6006f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
6016f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
6026f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
6105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
62079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCodec->setCallback(
621dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            std::unique_ptr<CodecBase::CodecCallback>(
622dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    new CodecCallback(new AMessage(kWhatCodecNotify, this))));
623dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mBufferChannel = mCodec->getBufferChannel();
624dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mBufferChannel->setCallback(
625dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            std::unique_ptr<CodecBase::BufferCallback>(
626dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    new BufferCallback(new AMessage(kWhatCodecNotify, this))));
6275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
6295778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
6305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
6315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
6325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
6335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
6345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
636db1221479a7ffe7094c51c463bbd36522ed106abRay Essick    if (mAnalyticsItem != NULL) {
637db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        if (nameIsType) {
638db1221479a7ffe7094c51c463bbd36522ed106abRay Essick            // name is the mime type
6398574195df5de20af5fc16d6f9da1b132d6d5bfeeRay Essick            mAnalyticsItem->setCString(kCodecMime, name.c_str());
640db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        } else {
6418574195df5de20af5fc16d6f9da1b132d6d5bfeeRay Essick            mAnalyticsItem->setCString(kCodecCodec, name.c_str());
642db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        }
6438574195df5de20af5fc16d6f9da1b132d6d5bfeeRay Essick        mAnalyticsItem->setCString(kCodecMode, mIsVideo ? "video" : "audio");
644db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        if (nameIsType)
645afb43f76821e6a63e17e6484289a40430ada6978Ray Essick            mAnalyticsItem->setInt32(kCodecEncoder, encoder);
646db1221479a7ffe7094c51c463bbd36522ed106abRay Essick    }
647db1221479a7ffe7094c51c463bbd36522ed106abRay Essick
64867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
64967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
650ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::Type type =
651ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            secureCodec ? MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
652ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::SubType subtype =
653ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
654ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(type, subtype, 1));
65567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
65667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
65767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
65837c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
65967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
66067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
66167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
66267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
66367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
66467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
66567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
66667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
66767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
66867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
66967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
6705778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
672c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
6731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
674c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
675c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
676c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
677c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
678c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
679c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
68090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarstatus_t MediaCodec::setOnFrameRenderedNotification(const sp<AMessage> &notify) {
68190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetNotification, this);
68290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setMessage("on-frame-rendered", notify);
68390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return msg->post();
68490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
68590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
6875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
6889dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        const sp<Surface> &nativeWindow,
6899dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        const sp<ICrypto> &crypto,
6909dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        uint32_t flags) {
6919dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang    return configure(format, nativeWindow, crypto, NULL, flags);
6929dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang}
6939dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang
6949dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhangstatus_t MediaCodec::configure(
6959dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        const sp<AMessage> &format,
696f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        const sp<Surface> &surface,
6971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
6989dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        const sp<IDescrambler> &descrambler,
6995778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
7001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
7015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
70267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
70367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
70467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
705afb43f76821e6a63e17e6484289a40430ada6978Ray Essick        if (!format->findInt32(kCodecRotation, &mRotationDegrees)) {
706505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang            mRotationDegrees = 0;
707505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        }
7082034457336d28124e0f9f3c625978052ae03fceaWei Jia
709db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        if (mAnalyticsItem != NULL) {
710afb43f76821e6a63e17e6484289a40430ada6978Ray Essick            mAnalyticsItem->setInt32(kCodecWidth, mVideoWidth);
711afb43f76821e6a63e17e6484289a40430ada6978Ray Essick            mAnalyticsItem->setInt32(kCodecHeight, mVideoHeight);
712afb43f76821e6a63e17e6484289a40430ada6978Ray Essick            mAnalyticsItem->setInt32(kCodecRotation, mRotationDegrees);
713db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        }
714db1221479a7ffe7094c51c463bbd36522ed106abRay Essick
7152034457336d28124e0f9f3c625978052ae03fceaWei Jia        // Prevent possible integer overflow in downstream code.
7162034457336d28124e0f9f3c625978052ae03fceaWei Jia        if (mInitIsEncoder
7172034457336d28124e0f9f3c625978052ae03fceaWei Jia                && (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
7182034457336d28124e0f9f3c625978052ae03fceaWei Jia            ALOGE("buffer size is too big, width=%d, height=%d", mVideoWidth, mVideoHeight);
7192034457336d28124e0f9f3c625978052ae03fceaWei Jia            return BAD_VALUE;
7202034457336d28124e0f9f3c625978052ae03fceaWei Jia        }
72167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
72267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
725f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    msg->setObject("surface", surface);
7261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
7279dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang    if (crypto != NULL || descrambler != NULL) {
7289dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        if (crypto != NULL) {
7299dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang            msg->setPointer("crypto", crypto.get());
7309dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        } else {
7319dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang            msg->setPointer("descrambler", descrambler.get());
7329dbe9a57bf0ae2494ec312d6c1b06feec20e9ec9Chong Zhang        }
733db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        if (mAnalyticsItem != NULL) {
734db1221479a7ffe7094c51c463bbd36522ed106abRay Essick            // XXX: save indication that it's crypto in some way...
735afb43f76821e6a63e17e6484289a40430ada6978Ray Essick            mAnalyticsItem->setInt32(kCodecCrypto, 1);
736db1221479a7ffe7094c51c463bbd36522ed106abRay Essick        }
73732c1bcda7c9fb429fe6c235184f8bb6aa7ef12dbDongwon Kang    } else if (mFlags & kFlagIsSecure) {
73832c1bcda7c9fb429fe6c235184f8bb6aa7ef12dbDongwon Kang        ALOGW("Crypto or descrambler should be given for secure codec");
7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
74167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
74267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
743f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
74467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
74567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
746ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::Type type = (mFlags & kFlagIsSecure) ?
747ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
748ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::SubType subtype =
749ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
750ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(type, subtype, 1));
75167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
75267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
753ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
75467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
75567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
75667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
75737c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
75867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
75967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
76067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
761f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
76267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
76367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
76467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
76567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
76667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
76767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
76867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
76967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
77067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
77167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
77267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
77367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
77467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
77567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
77667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
777f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
778f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
781cefac14261a32fb856b0d1ab31541787112e306eHassan Shojaniastatus_t MediaCodec::releaseCrypto()
782cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania{
783cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    ALOGV("releaseCrypto");
784cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
785cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    sp<AMessage> msg = new AMessage(kWhatDrmReleaseCrypto, this);
786cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
787cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    sp<AMessage> response;
788cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    status_t status = msg->postAndAwaitResponse(&response);
789cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
790cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    if (status == OK && response != NULL) {
791cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        CHECK(response->findInt32("status", &status));
792cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        ALOGV("releaseCrypto ret: %d ", status);
793cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    }
794cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    else {
795cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        ALOGE("releaseCrypto err: %d", status);
796cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    }
797cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
798cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    return status;
799cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania}
800cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
801cefac14261a32fb856b0d1ab31541787112e306eHassan Shojaniavoid MediaCodec::onReleaseCrypto(const sp<AMessage>& msg)
802cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania{
803cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    status_t status = INVALID_OPERATION;
804cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    if (mCrypto != NULL) {
805cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        ALOGV("onReleaseCrypto: mCrypto: %p (%d)", mCrypto.get(), mCrypto->getStrongCount());
806cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        mBufferChannel->setCrypto(NULL);
807cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        // TODO change to ALOGV
808cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        ALOGD("onReleaseCrypto: [before clear]  mCrypto: %p (%d)",
809cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania                mCrypto.get(), mCrypto->getStrongCount());
810cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        mCrypto.clear();
811cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
812cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        status = OK;
813cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    }
814cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    else {
815cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania        ALOGW("onReleaseCrypto: No mCrypto. err: %d", status);
816cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania    }
817cefac14261a32fb856b0d1ab31541787112e306eHassan Shojania
818