MediaCodec.cpp revision dff26e5f53b248fd8cc6605850240c7e7c5438dc
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>
40dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim#include <media/stagefright/foundation/AUtils.h>
41ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h>
425778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h>
437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h>
442606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h>
456f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h>
46e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h>
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h>
48744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h>
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h>
50d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXClient.h>
51d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h>
528b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar#include <media/stagefright/SurfaceUtils.h>
5399e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <mediautils/BatteryNotifier.h>
542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h>
552606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h>
562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h>
57e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
585778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
600d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsiehstatic int64_t getId(const sp<IResourceManagerClient> &client) {
6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return (int64_t) client.get();
6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) {
6547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    return (err == NO_MEMORY);
6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2;
694b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wustatic const int kMaxReclaimWaitTimeInUs = 500000;  // 0.5s
70dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimstatic const int kNumBuffersAlign = 16;
7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim////////////////////////////////////////////////////////////////////////////////
7379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient {
75090ef604f81447eab4aa0a5b45d6307482573560Chih-Hung Hsieh    explicit ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {}
7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool reclaimResource() {
7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
7967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (codec == NULL) {
8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // codec is already gone.
8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            return true;
8267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
8347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        status_t err = codec->reclaim();
844b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        if (err == WOULD_BLOCK) {
854b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            ALOGD("Wait for the client to release codec.");
864b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            usleep(kMaxReclaimWaitTimeInUs);
874b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            ALOGD("Try to reclaim again.");
884b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu            err = codec->reclaim(true /* force */);
894b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        }
9067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK) {
9167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGW("ResourceManagerClient failed to release codec with err %d", err);
9267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
9367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (err == OK);
9467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
9567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
968f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    virtual String8 getName() {
978f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        String8 ret;
988f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        sp<MediaCodec> codec = mMediaCodec.promote();
998f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec == NULL) {
1008f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            // codec is already gone.
1018f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            return ret;
1028f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
1038f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu
1048f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        AString name;
1058f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        if (codec->getName(&name) == OK) {
1068f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu            ret.setTo(name.c_str());
1078f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        }
1088f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu        return ret;
1098f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu    }
11067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
11167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected:
11267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual ~ResourceManagerClient() {}
11367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
11467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate:
11567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    wp<MediaCodec> mMediaCodec;
11667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
11767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
11867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu};
11967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
12068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid)
12168845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        : mPid(pid) {
12268845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    if (mPid == MediaCodec::kNoPid) {
12368845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        mPid = IPCThreadState::self()->getCallingPid();
12468845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    }
12567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
12667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
12767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
12867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService != NULL) {
12967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        IInterface::asBinder(mService)->unlinkToDeath(this);
13067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
13167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
13267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
13367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() {
13467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IServiceManager> sm = defaultServiceManager();
13567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
13667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService = interface_cast<IResourceManagerService>(binder);
13767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
13867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        ALOGE("Failed to get ResourceManagerService");
13967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
14067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
141e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu    IInterface::asBinder(mService)->linkToDeath(this);
14267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
14367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
14467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
14567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    ALOGW("ResourceManagerService died.");
14667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
14767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mService.clear();
14867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
14967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
15067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource(
15167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        int64_t clientId,
1520d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsieh        const sp<IResourceManagerClient> &client,
15367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        const Vector<MediaResource> &resources) {
15467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
15567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
15667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
15767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
15837c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    mService->addResource(mPid, clientId, client, resources);
15967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
16067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
16167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
16267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
16367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
16467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return;
16567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
16637c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    mService->removeResource(mPid, clientId);
16767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
16867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
16967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
17037c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu        const Vector<MediaResource> &resources) {
17167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Mutex::Autolock _l(mLock);
17267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mService == NULL) {
17367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return false;
17467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
17537c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu    return mService->reclaimResource(mPid, resources);
17667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
17767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
17879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim////////////////////////////////////////////////////////////////////////////////
17979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
180dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimMediaCodec::BufferInfo::BufferInfo() : mOwnedByClient(false) {}
181dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
182dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim////////////////////////////////////////////////////////////////////////////////
183dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
18479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimnamespace {
18579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
18679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimenum {
18779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatFillThisBuffer      = 'fill',
18879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatDrainThisBuffer     = 'drai',
18979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatEOS                 = 'eos ',
190dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    kWhatStartCompleted      = 'Scom',
19179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatStopCompleted       = 'scom',
19279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatReleaseCompleted    = 'rcom',
19379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatFlushCompleted      = 'fcom',
19479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatError               = 'erro',
19579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatComponentAllocated  = 'cAll',
19679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatComponentConfigured = 'cCon',
19779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatInputSurfaceCreated = 'isfc',
19879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatInputSurfaceAccepted = 'isfa',
19979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatSignaledInputEOS    = 'seos',
20079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    kWhatOutputFramesRendered = 'outR',
201dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    kWhatOutputBuffersChanged = 'outC',
20279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim};
20379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
204dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimclass BufferCallback : public CodecBase::BufferCallback {
20579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimpublic:
206dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    explicit BufferCallback(const sp<AMessage> &notify);
207dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual ~BufferCallback() = default;
208dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
209dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual void onInputBufferAvailable(
210dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            size_t index, const sp<MediaCodecBuffer> &buffer) override;
211dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual void onOutputBufferAvailable(
212dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            size_t index, const sp<MediaCodecBuffer> &buffer) override;
213dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimprivate:
214dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    const sp<AMessage> mNotify;
215dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim};
216dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
217dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimBufferCallback::BufferCallback(const sp<AMessage> &notify)
218dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    : mNotify(notify) {}
219dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
220dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid BufferCallback::onInputBufferAvailable(
221dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        size_t index, const sp<MediaCodecBuffer> &buffer) {
222dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    sp<AMessage> notify(mNotify->dup());
223dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatFillThisBuffer);
224dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setSize("index", index);
225dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setObject("buffer", buffer);
226dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->post();
227dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
228dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
229dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid BufferCallback::onOutputBufferAvailable(
230dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        size_t index, const sp<MediaCodecBuffer> &buffer) {
231dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    sp<AMessage> notify(mNotify->dup());
232dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatDrainThisBuffer);
233dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setSize("index", index);
234dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setObject("buffer", buffer);
235dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->post();
236dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
237dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
238dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimclass CodecCallback : public CodecBase::CodecCallback {
239dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimpublic:
240dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    explicit CodecCallback(const sp<AMessage> &notify);
241dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual ~CodecCallback() = default;
24279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
24379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onEos(status_t err) override;
244dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual void onStartCompleted() override;
24579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onStopCompleted() override;
24679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onReleaseCompleted() override;
24779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onFlushCompleted() override;
24879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onError(status_t err, enum ActionCode actionCode) override;
24979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onComponentAllocated(const char *componentName) override;
25079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onComponentConfigured(
25179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) override;
25279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onInputSurfaceCreated(
25379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &inputFormat,
25479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &outputFormat,
25579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<BufferProducerWrapper> &inputSurface) override;
25679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onInputSurfaceCreationFailed(status_t err) override;
25779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onInputSurfaceAccepted(
25879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &inputFormat,
25979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim            const sp<AMessage> &outputFormat) override;
26079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onInputSurfaceDeclined(status_t err) override;
26179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onSignaledInputEOS(status_t err) override;
26279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    virtual void onOutputFramesRendered(const std::list<FrameRenderTracker::Info> &done) override;
263dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    virtual void onOutputBuffersChanged() override;
26479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kimprivate:
26579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    const sp<AMessage> mNotify;
26679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim};
26779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
268dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik KimCodecCallback::CodecCallback(const sp<AMessage> &notify) : mNotify(notify) {}
26979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
270dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onEos(status_t err) {
27179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
272dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatEOS);
273dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("err", err);
274fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim    notify->post();
275fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim}
276fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim
277dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onStartCompleted() {
278fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim    sp<AMessage> notify(mNotify->dup());
279dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatStartCompleted);
28079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
28179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
28279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
283dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onStopCompleted() {
28479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
28579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatStopCompleted);
28679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
28779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
28879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
289dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onReleaseCompleted() {
29079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
29179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatReleaseCompleted);
29279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
29379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
29479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
295dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onFlushCompleted() {
29679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
29779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatFlushCompleted);
29879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
29979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
30079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
301dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onError(status_t err, enum ActionCode actionCode) {
30279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
30379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatError);
30479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("err", err);
30579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("actionCode", actionCode);
30679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
30779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
30879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
309dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onComponentAllocated(const char *componentName) {
31079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
31179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatComponentAllocated);
31279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setString("componentName", componentName);
31379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
31479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
31579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
316dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onComponentConfigured(
31779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &inputFormat, const sp<AMessage> &outputFormat) {
31879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
31979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatComponentConfigured);
32079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("input-format", inputFormat);
32179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("output-format", outputFormat);
32279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
32379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
32479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
325dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onInputSurfaceCreated(
32679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &inputFormat,
32779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &outputFormat,
32879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<BufferProducerWrapper> &inputSurface) {
32979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
33079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatInputSurfaceCreated);
33179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("input-format", inputFormat);
33279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("output-format", outputFormat);
33379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setObject("input-surface", inputSurface);
33479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
33579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
33679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
337dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onInputSurfaceCreationFailed(status_t err) {
33879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
33979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatInputSurfaceCreated);
34079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("err", err);
34179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
34279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
34379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
344dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onInputSurfaceAccepted(
34579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &inputFormat,
34679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        const sp<AMessage> &outputFormat) {
34779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
34879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatInputSurfaceAccepted);
34979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("input-format", inputFormat);
35079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setMessage("output-format", outputFormat);
35179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
35279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
35379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
354dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onInputSurfaceDeclined(status_t err) {
35579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
35679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatInputSurfaceAccepted);
35779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("err", err);
35879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
35979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
36079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
361dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onSignaledInputEOS(status_t err) {
36279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
36379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatSignaledInputEOS);
36479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    if (err != OK) {
36579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        notify->setInt32("err", err);
36679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    }
36779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->post();
36879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
36979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
370dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onOutputFramesRendered(const std::list<FrameRenderTracker::Info> &done) {
37179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    sp<AMessage> notify(mNotify->dup());
37279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    notify->setInt32("what", kWhatOutputFramesRendered);
37379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    if (MediaCodec::CreateFramesRenderedMessage(done, notify)) {
37479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim        notify->post();
37579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    }
37679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}
37779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
378dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kimvoid CodecCallback::onOutputBuffersChanged() {
379dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    sp<AMessage> notify(mNotify->dup());
380dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->setInt32("what", kWhatOutputBuffersChanged);
381dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    notify->post();
382dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim}
383dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
38479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim}  // namespace
38579054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
38679054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim////////////////////////////////////////////////////////////////////////////////
38779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim
3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
3895778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType(
390f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err, pid_t pid,
391f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        uid_t uid) {
392f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    sp<MediaCodec> codec = new MediaCodec(looper, pid, uid);
3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
394251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(mime, true /* nameIsType */, encoder);
395251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
396251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
397251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
398251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
4025778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName(
403f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        const sp<ALooper> &looper, const AString &name, status_t *err, pid_t pid, uid_t uid) {
404f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    sp<MediaCodec> codec = new MediaCodec(looper, pid, uid);
4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
406251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */);
407251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    if (err != NULL) {
408251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        *err = ret;
409251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
410251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    return ret == OK ? codec : NULL; // NULL deallocates codec.
4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber
413d291c222357303b9611cab89d0c3b047584ef377Chong Zhang// static
4145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t MediaCodec::QueryCapabilities(
4155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        const AString &name, const AString &mime, bool isEncoder,
4165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        sp<MediaCodecInfo::Capabilities> *caps /* nonnull */) {
4175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // TRICKY: this method is used by MediaCodecList/Info during its
4185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // initialization. As such, we cannot create a MediaCodec instance
4195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // because that requires an initialized MediaCodecList.
4205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
4215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    sp<CodecBase> codec = GetCodecBase(name);
4225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (codec == NULL) {
4235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NAME_NOT_FOUND;
4245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
4255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
4265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    return codec->queryCapabilities(name, mime, isEncoder, caps);
4275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
4285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
4295b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar// static
430d291c222357303b9611cab89d0c3b047584ef377Chong Zhangsp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
431d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    OMXClient client;
432addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    if (client.connect() != OK) {
433addf2cbb120346ae42e78fa739245a353db5edadChong Zhang        ALOGE("Failed to connect to OMX to create persistent input surface.");
43479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang        return NULL;
43579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang    }
43679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
437addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<IOMX> omx = client.interface();
43879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang
439d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<IGraphicBufferProducer> bufferProducer;
440addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    sp<IGraphicBufferSource> bufferSource;
441d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
442addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    status_t err = omx->createInputSurface(&bufferProducer, &bufferSource);
443d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
444d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    if (err != OK) {
445d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        ALOGE("Failed to create persistent input surface.");
446d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        return NULL;
447d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    }
448d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
449addf2cbb120346ae42e78fa739245a353db5edadChong Zhang    return new PersistentSurface(bufferProducer, bufferSource);
450d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
451d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
452f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei JiaMediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    : mState(UNINITIALIZED),
45447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu      mReleasedByResourceManager(false),
4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mLooper(looper),
45692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar      mCodec(NULL),
4577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden      mReplyID(0),
4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mFlags(0),
459251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung      mStickyError(OK),
4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mSoftRenderer(NULL),
461ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar      mResourceManagerClient(new ResourceManagerClient(this)),
46268845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu      mResourceManagerService(new ResourceManagerServiceProxy(pid)),
4632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mBatteryStatNotified(false),
4642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang      mIsVideo(false),
46567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoWidth(0),
46667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu      mVideoHeight(0),
467505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang      mRotationDegrees(0),
4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputTimeoutGeneration(0),
4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueInputReplyID(0),
4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber      mDequeueOutputTimeoutGeneration(0),
4716507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden      mDequeueOutputReplyID(0),
4723d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHaveInputSurface(false),
4733d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang      mHavePendingInputBuffers(false) {
474f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    if (uid == kNoUid) {
475f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        mUid = IPCThreadState::self()->getCallingUid();
476f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    } else {
477f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        mUid = uid;
478f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia    }
4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4815778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() {
4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK_EQ(mState, UNINITIALIZED);
48367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->removeResource(getId(mResourceManagerClient));
4845778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
4855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4865778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static
4875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse(
4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &msg, sp<AMessage> *response) {
4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err = msg->postAndAwaitResponse(response);
4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (err != OK) {
4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
4935778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4955778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!(*response)->findInt32("err", &err)) {
4965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        err = OK;
4975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return err;
5005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
5015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) {
50347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    int32_t finalErr = err;
50447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
50547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        // override the err code if MediaCodec has been released by ResourceManager.
50647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        finalErr = DEAD_OBJECT;
50747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
50847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
509c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response = new AMessage;
51047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    response->setInt32("err", finalErr);
511c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    response->postReply(replyID);
512c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
513c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
5145b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static
5155b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarsp<CodecBase> MediaCodec::GetCodecBase(const AString &name, bool nameIsType) {
5165b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    // at this time only ACodec specifies a mime type.
5175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (nameIsType || name.startsWithIgnoreCase("omx.")) {
5185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return new ACodec;
5195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else if (name.startsWithIgnoreCase("android.filter.")) {
5205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return new MediaFilter;
5215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    } else {
5225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar        return NULL;
5235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    }
5245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar}
5255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
526dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) {
52767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->init();
52867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
529671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // save init parameters for reset
530671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitName = name;
531671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitNameIsType = nameIsType;
532671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mInitIsEncoder = encoder;
533671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
5345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // Current video decoders do not return from OMX_FillThisBuffer
5355778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // quickly, violating the OpenMAX specs, until that is remedied
5365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // we need to invest in an extra looper to free the main event
5375778822d86b0337407514b9372562b86edfa91cdAndreas Huber    // queue.
538744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
5395b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    mCodec = GetCodecBase(name, nameIsType);
5405b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    if (mCodec == NULL) {
541744f5739019d1fd917f981e740b353c3d73fd1a8David Smith        return NAME_NOT_FOUND;
542744f5739019d1fd917f981e740b353c3d73fd1a8David Smith    }
543744f5739019d1fd917f981e740b353c3d73fd1a8David Smith
54467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    bool secureCodec = false;
545dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung    if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) {
54667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        mIsVideo = true;
5476f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen    } else {
5486f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        AString tmp = name;
5496f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (tmp.endsWith(".secure")) {
55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            secureCodec = true;
5516f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            tmp.erase(tmp.size() - 7, 7);
5526f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
55360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
55448a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        if (mcl == NULL) {
55548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            mCodec = NULL;  // remove the codec.
55648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung            return NO_INIT; // if called from Java should raise IOException
55748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung        }
5586f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        ssize_t codecIdx = mcl->findCodecByName(tmp.c_str());
5596f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        if (codecIdx >= 0) {
56060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx);
56160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            Vector<AString> mimes;
56260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            info->getSupportedMimes(&mimes);
56360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar            for (size_t i = 0; i < mimes.size(); i++) {
56460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                if (mimes[i].startsWith("video/")) {
56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mIsVideo = true;
56660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar                    break;
5676f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen                }
5686f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen            }
5696f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen        }
5705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5715778822d86b0337407514b9372562b86edfa91cdAndreas Huber
57267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
57367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // video codec needs dedicated looper
5745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mCodecLooper == NULL) {
5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper = new ALooper;
5765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->setName("CodecLooper");
5775778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
5785778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
5795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5805778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mCodecLooper->registerHandler(mCodec);
5815778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
5825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mLooper->registerHandler(mCodec);
5835778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
5845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mLooper->registerHandler(this);
5865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
58779054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim    mCodec->setCallback(
588dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            std::unique_ptr<CodecBase::CodecCallback>(
589dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    new CodecCallback(new AMessage(kWhatCodecNotify, this))));
590dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mBufferChannel = mCodec->getBufferChannel();
591dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mBufferChannel->setCallback(
592dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            std::unique_ptr<CodecBase::BufferCallback>(
593dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    new BufferCallback(new AMessage(kWhatCodecNotify, this))));
5945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatInit, this);
5965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setString("name", name);
5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("nameIsType", nameIsType);
5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
5995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (nameIsType) {
6005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        msg->setInt32("encoder", encoder);
6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
605ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::Type type =
606ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            secureCodec ? MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
607ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::SubType subtype =
608ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
609ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(type, subtype, 1));
61067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
61167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
61267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
61337c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
61467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
61567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
61667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
61767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
61867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
61967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
62067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
62167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
62267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
62367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
62467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
6255778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
6265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
627c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) {
6281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetCallback, this);
629c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    msg->setMessage("callback", callback);
630c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
631c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    sp<AMessage> response;
632c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    return PostAndAwaitResponse(msg, &response);
633c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
63590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarstatus_t MediaCodec::setOnFrameRenderedNotification(const sp<AMessage> &notify) {
63690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetNotification, this);
63790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    msg->setMessage("on-frame-rendered", notify);
63890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return msg->post();
63990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
64090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
6415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure(
6425778822d86b0337407514b9372562b86edfa91cdAndreas Huber        const sp<AMessage> &format,
643f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        const sp<Surface> &surface,
6441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        const sp<ICrypto> &crypto,
6455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t flags) {
6461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatConfigure, this);
6475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
64867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (mIsVideo) {
64967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("width", &mVideoWidth);
65067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        format->findInt32("height", &mVideoHeight);
651505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        if (!format->findInt32("rotation-degrees", &mRotationDegrees)) {
652505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang            mRotationDegrees = 0;
653505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        }
6542034457336d28124e0f9f3c625978052ae03fceaWei Jia
6552034457336d28124e0f9f3c625978052ae03fceaWei Jia        // Prevent possible integer overflow in downstream code.
6562034457336d28124e0f9f3c625978052ae03fceaWei Jia        if (mInitIsEncoder
6572034457336d28124e0f9f3c625978052ae03fceaWei Jia                && (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) {
6582034457336d28124e0f9f3c625978052ae03fceaWei Jia            ALOGE("buffer size is too big, width=%d, height=%d", mVideoWidth, mVideoHeight);
6592034457336d28124e0f9f3c625978052ae03fceaWei Jia            return BAD_VALUE;
6602034457336d28124e0f9f3c625978052ae03fceaWei Jia        }
66167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
66267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setMessage("format", format);
6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
665f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    msg->setObject("surface", surface);
6661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
6671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (crypto != NULL) {
6681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        msg->setPointer("crypto", crypto.get());
6695778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
6705778822d86b0337407514b9372562b86edfa91cdAndreas Huber
67167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // save msg for reset
67267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mConfigureMsg = msg;
673f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
67467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
67567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
676ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::Type type = (mFlags & kFlagIsSecure) ?
677ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
678ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::SubType subtype =
679ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
680ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(type, subtype, 1));
68167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
68267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
683ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
68467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
68567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
68667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
68737c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
68867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
68967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
69067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
691f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang
69267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
69367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
69467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (err != OK && err != INVALID_OPERATION) {
69567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // MediaCodec now set state to UNINITIALIZED upon any fatal error.
69667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // To maintain backward-compatibility, do a reset() to put codec
69767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // back into INITIALIZED state.
69867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // But don't reset if the err is INVALID_OPERATION, which means
69967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // the configure failure is due to wrong state.
70067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
70167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            ALOGE("configure failed with err 0x%08x, resetting...", err);
70267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            reset();
70367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
70467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
70567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
70667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
707f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    }
708f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang    return err;
7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber
7118f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangstatus_t MediaCodec::setInputSurface(
712d291c222357303b9611cab89d0c3b047584ef377Chong Zhang        const sp<PersistentSurface> &surface) {
7138f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang    sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this);
714d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    msg->setObject("input-surface", surface.get());
715d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
716d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    sp<AMessage> response;
717d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    return PostAndAwaitResponse(msg, &response);
718d291c222357303b9611cab89d0c3b047584ef377Chong Zhang}
719d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
7201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::setSurface(const sp<Surface> &surface) {
7211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetSurface, this);
7221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    msg->setObject("surface", surface);
7231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    sp<AMessage> response;
7251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return PostAndAwaitResponse(msg, &response);
7261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
7271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
7287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface(
7297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<IGraphicBufferProducer>* bufferProducer) {
7301d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this);
7317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
7327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
7337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    status_t err = PostAndAwaitResponse(msg, &response);
7347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    if (err == NO_ERROR) {
7357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        // unwrap the sp<IGraphicBufferProducer>
7367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<RefBase> obj;
7377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        bool found = response->findObject("input-surface", &obj);
7387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        CHECK(found);
7397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        sp<BufferProducerWrapper> wrapper(
7407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                static_cast<BufferProducerWrapper*>(obj.get()));
7417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        *bufferProducer = wrapper->getBufferProducer();
7427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    } else {
7437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        ALOGW("createInputSurface failed, err=%d", err);
7447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    }
7457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return err;
7467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
7477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
74867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() {
74967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    if (!mIsVideo) {
75067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return 0;
75167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
75267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
75367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    uint64_t size = 0;
75467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]);
75567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (size_t i = 0; i < portNum; ++i) {
75667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        // TODO: this is just an estimation, we should get the real buffer size from ACodec.
75767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2;
75867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
75967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return size;
76067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
76167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
762ea15fd29af81490311af9e12949b43524c39400eRonghua Wuvoid MediaCodec::addResource(
763ea15fd29af81490311af9e12949b43524c39400eRonghua Wu        MediaResource::Type type, MediaResource::SubType subtype, uint64_t value) {
76467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
765c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu    resources.push_back(MediaResource(type, subtype, value));
76667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    mResourceManagerService->addResource(
76737c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            getId(mResourceManagerClient), mResourceManagerClient, resources);
76867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}
76967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
7705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() {
7711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStart, this);
7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
77367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    status_t err;
77467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    Vector<MediaResource> resources;
775ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::Type type = (mFlags & kFlagIsSecure) ?
776ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            MediaResource::kSecureCodec : MediaResource::kNonSecureCodec;
777ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    MediaResource::SubType subtype =
778ea15fd29af81490311af9e12949b43524c39400eRonghua Wu            mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec;
779ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(type, subtype, 1));
78067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // Don't know the buffer size at this point, but it's fine to use 1 because
78167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    // the reclaimResource call doesn't consider the requester's buffer size for now.
782ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1));
78367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    for (int i = 0; i <= kMaxRetry; ++i) {
78467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (i > 0) {
78567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Don't try to reclaim resource for the first time.
78637c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu            if (!mResourceManagerService->reclaimResource(resources)) {
78767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
78867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
78967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            // Recover codec from previous error before retry start.
79067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = reset();
79167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
79267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to reset codec");
79367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
79467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
79567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            sp<AMessage> response;
79667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            err = PostAndAwaitResponse(mConfigureMsg, &response);
79767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            if (err != OK) {
79867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                ALOGE("retrying start: failed to configure codec");
79967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                break;
80067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            }
80167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
80267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
80367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        sp<AMessage> response;
80467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        err = PostAndAwaitResponse(msg, &response);
80567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        if (!isResourceError(err)) {
80667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu            break;
80767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        }
80867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
80967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    return err;
8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() {
8131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatStop, this);
8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
8165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
8185778822d86b0337407514b9372562b86edfa91cdAndreas Huber
8194b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wubool MediaCodec::hasPendingBuffer(int portIndex) {
820dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    return std::any_of(
821dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mPortBuffers[portIndex].begin(), mPortBuffers[portIndex].end(),
822dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            [](const BufferInfo &info) { return info.mOwnedByClient; });
8234b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu}
8244b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
8254b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wubool MediaCodec::hasPendingBuffer() {
8264b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu    return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput);
8274b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu}
8284b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
8294b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wustatus_t MediaCodec::reclaim(bool force) {
83058828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu    ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str());
83147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    sp<AMessage> msg = new AMessage(kWhatRelease, this);
83247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    msg->setInt32("reclaimed", 1);
8334b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu    msg->setInt32("force", force ? 1 : 0);
83447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
83547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    sp<AMessage> response;
8360abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu    status_t ret = PostAndAwaitResponse(msg, &response);
8370abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu    if (ret == -ENOENT) {
8380abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu        ALOGD("MediaCodec looper is gone, skip reclaim");
8390abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu        ret = OK;
8400abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu    }
8410abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu    return ret;
84247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu}
84347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
844c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() {
8451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRelease, this);
846c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
847c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    sp<AMessage> response;
848c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    return PostAndAwaitResponse(msg, &response);
849c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber}
850c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
851671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() {
852671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    /* When external-facing MediaCodec object is created,
853671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       it is already initialized.  Thus, reset is essentially
854671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar       release() followed by init(), plus clearing the state */
855671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
856671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    status_t err = release();
857671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
858671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // unregister handlers
859671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (mCodec != NULL) {
860671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        if (mCodecLooper != NULL) {
861671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mCodecLooper->unregisterHandler(mCodec->id());
862671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        } else {
863671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar            mLooper->unregisterHandler(mCodec->id());
864671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        }
865671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mCodec = NULL;
866671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
867671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mLooper->unregisterHandler(id());
868671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
869671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mFlags = 0;    // clear all flags
870251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    mStickyError = OK;
871671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
872671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    // reset state not reset by setState(UNINITIALIZED)
873671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mReplyID = 0;
874671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputReplyID = 0;
875671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputReplyID = 0;
876671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueInputTimeoutGeneration = 0;
877671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mDequeueOutputTimeoutGeneration = 0;
878671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    mHaveInputSurface = false;
879671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
880671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    if (err == OK) {
881dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        err = init(mInitName, mInitNameIsType, mInitIsEncoder);
882671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
883671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    return err;
884671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar}
885671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
8865778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer(
8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t index,
8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t offset,
8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t size,
8905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t presentationTimeUs,
8915b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
8925b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
8935b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
8945b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
8955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
8965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
8971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("offset", offset);
9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("size", size);
9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("flags", flags);
9035b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
9045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer(
9104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t index,
9114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t offset,
9124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const CryptoPlugin::SubSample *subSamples,
9134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size_t numSubSamples,
9144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t key[16],
9154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        const uint8_t iv[16],
9164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CryptoPlugin::Mode mode,
91718cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker        const CryptoPlugin::Pattern &pattern,
9184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int64_t presentationTimeUs,
9195b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        uint32_t flags,
9205b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg) {
9215b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    if (errorDetailMsg != NULL) {
9225b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        errorDetailMsg->clear();
9235b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    }
9245b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
9251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
9264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("index", index);
9274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("offset", offset);
9284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("subSamples", (void *)subSamples);
9294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setSize("numSubSamples", numSubSamples);
9304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("key", (void *)key);
9314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setPointer("iv", (void *)iv);
9324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("mode", mode);
93318cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker    msg->setInt32("encryptBlocks", pattern.mEncryptBlocks);
93418cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker    msg->setInt32("skipBlocks", pattern.mSkipBlocks);
9354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt64("timeUs", presentationTimeUs);
9364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    msg->setInt32("flags", flags);
9375b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    msg->setPointer("errorDetailMsg", errorDetailMsg);
9384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
9394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    sp<AMessage> response;
9405b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    status_t err = PostAndAwaitResponse(msg, &response);
9415b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
9425b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    return err;
9434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber}
9444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
9455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
9461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this);
9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9605778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer(
9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *index,
9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *offset,
9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t *size,
9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t *presentationTimeUs,
9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        uint32_t *flags,
9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeoutUs) {
9671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this);
9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt64("timeoutUs", timeoutUs);
9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("index", index));
9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("offset", offset));
9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findSize("size", size));
9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt64("timeUs", presentationTimeUs));
9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findInt32("flags", (int32_t *)flags));
9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9855778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) {
9861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("render", true);
9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
994fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) {
9951d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
996fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setSize("index", index);
997fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt32("render", true);
998fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    msg->setInt64("timestampNs", timestampNs);
999fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
1000fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    sp<AMessage> response;
1001fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar    return PostAndAwaitResponse(msg, &response);
1002fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar}
1003fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
10045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) {
10051d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this);
10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setSize("index", index);
10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() {
10131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this);
10147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    sp<AMessage> response;
10167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    return PostAndAwaitResponse(msg, &response);
10177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden}
10187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
10195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const {
10201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this);
10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber    status_t err;
10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return err;
10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(response->findMessage("format", format));
10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1033e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const {
10341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this);
1035e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1036e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    sp<AMessage> response;
1037e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    status_t err;
1038e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
1039e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        return err;
1040e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
1041e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1042e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    CHECK(response->findMessage("format", format));
1043e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1044e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    return OK;
1045e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar}
1046e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
1047717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const {
10481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetName, this);
1049717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1050717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    sp<AMessage> response;
1051717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    status_t err;
1052717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if ((err = PostAndAwaitResponse(msg, &response)) != OK) {
1053717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        return err;
1054717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
1055717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1056717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    CHECK(response->findString("name", name));
1057717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
1058717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    return OK;
1059717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo}
1060717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
10617e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getInputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
10621d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexInput);
10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10707e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getOutputBuffers(Vector<sp<MediaCodecBuffer> > *buffers) const {
10711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatGetBuffers, this);
10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setInt32("portIndex", kPortIndexOutput);
10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber    msg->setPointer("buffers", buffers);
10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
10797e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getOutputBuffer(size_t index, sp<MediaCodecBuffer> *buffer) {
10807bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
10817bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, buffer, &format);
10827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
10837bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
10847bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) {
10857e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim    sp<MediaCodecBuffer> buffer;
10867bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexOutput, index, &buffer, format);
10877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
10887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
10897e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kimstatus_t MediaCodec::getInputBuffer(size_t index, sp<MediaCodecBuffer> *buffer) {
10907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    sp<AMessage> format;
10917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return getBufferAndFormat(kPortIndexInput, index, buffer, &format);
10927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
10937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
10940e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const {
10950e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    return mState == STARTED || mState == FLUSHED;
10960e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar}
10970e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar
10987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat(
10997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        size_t portIndex, size_t index,
11007e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        sp<MediaCodecBuffer> *buffer, sp<AMessage> *format) {
11017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // use mutex instead of a context switch
110247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    if (mReleasedByResourceManager) {
1103b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - resource already released");
110447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        return DEAD_OBJECT;
110547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu    }
110647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
1107b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (buffer == NULL) {
11087e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        ALOGE("getBufferAndFormat - null MediaCodecBuffer");
1109b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
1110b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
1111b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
1112b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (format == NULL) {
1113b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - null AMessage");
1114b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
1115b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
1116b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
11177bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    buffer->clear();
11187bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    format->clear();
1119b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
11200e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
1121b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - not executing");
11227bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return INVALID_OPERATION;
11237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
11247bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
11257bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we do not want mPortBuffers to change during this section
11267bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // we also don't want mOwnedByClient to change during this
11277bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
1128b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
1129dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    std::vector<BufferInfo> &buffers = mPortBuffers[portIndex];
1130dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (index >= buffers.size()) {
1131b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - trying to get buffer with "
1132dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim              "bad index (index=%zu buffer_size=%zu)", index, buffers.size());
1133b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
11347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
1135b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
1136dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    const BufferInfo &info = buffers[index];
1137b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    if (!info.mOwnedByClient) {
1138b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        ALOGE("getBufferAndFormat - invalid operation "
11390362655ca9494052f348f83dabecf9ea27003976Aaron Vaage              "(the index %zu is not owned by client)", index);
1140b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage        return INVALID_OPERATION;
1141b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage    }
1142b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
11434811923e80a8abefa278307ebf8cc9b0294ba67fWonsik Kim    *buffer = info.mData;
1144fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    *format = info.mData->format();
1145b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage
11467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    return OK;
11477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar}
11487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
11495778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() {
11501d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatFlush, this);
11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response;
11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return PostAndAwaitResponse(msg, &response);
11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1156496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() {
11571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    (new AMessage(kWhatRequestIDRFrame, this))->post();
1158496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1159496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber    return OK;
1160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber}
1161496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
1162575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
11631d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this);
1164575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->setMessage("notify", notify);
1165575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    msg->post();
1166575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
1167575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber////////////////////////////////////////////////////////////////////////////////
11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11705778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() {
11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueInputPending) {
1172c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueInputTimeoutGeneration;
11755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueInputReplyID = 0;
11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueInputPending;
11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (mFlags & kFlagDequeueOutputPending) {
1180c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ++mDequeueOutputTimeoutGeneration;
11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mDequeueOutputReplyID = 0;
11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagDequeueOutputPending;
11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11883f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
11890e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueInputPending))) {
1191c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        PostReplyWithError(replyID, INVALID_OPERATION);
11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return true;
1193251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
1194251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        PostReplyWithError(replyID, getStickyError());
1195251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return true;
11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber    ssize_t index = dequeuePortBuffer(kPortIndexInput);
11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index < 0) {
12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK_EQ(index, -EAGAIN);
12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return false;
12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    sp<AMessage> response = new AMessage;
12065778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->setSize("index", index);
12075778822d86b0337407514b9372562b86edfa91cdAndreas Huber    response->postReply(replyID);
12085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12095778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
12105778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12123f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
12130e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting() || (mFlags & kFlagIsAsync)
12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber            || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
121547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INVALID_OPERATION);
1216251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    } else if (mFlags & kFlagStickyError) {
121747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, getStickyError());
12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputBuffersChanged) {
121947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED);
12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else if (mFlags & kFlagOutputFormatChanged) {
122247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        PostReplyWithError(replyID, INFO_FORMAT_CHANGED);
12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber    } else {
122547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        sp<AMessage> response = new AMessage;
12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber        ssize_t index = dequeuePortBuffer(kPortIndexOutput);
12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (index < 0) {
12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK_EQ(index, -EAGAIN);
12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            return false;
12315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12337e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        const sp<MediaCodecBuffer> &buffer =
1234dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mPortBuffers[kPortIndexOutput][index].mData;
12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("index", index);
12375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("offset", buffer->offset());
12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setSize("size", buffer->size());
12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int64_t timeUs;
12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt64("timeUs", timeUs);
12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1245dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        int32_t flags;
1246dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        CHECK(buffer->meta()->findInt32("flags", &flags));
12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber        response->setInt32("flags", flags);
124947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        response->postReply(replyID);
12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return true;
12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12555778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    switch (msg->what()) {
12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatCodecNotify:
12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t what;
12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("what", &what));
12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            switch (what) {
126379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatError:
12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1265251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    int32_t err, actionCode;
1266251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("err", &err));
1267251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    CHECK(msg->findInt32("actionCode", &actionCode));
12685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12699e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                    ALOGE("Codec reported err %#x, actionCode %d, while in state %d",
12709e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            err, actionCode, mState);
1271251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                    if (err == DEAD_OBJECT) {
1272aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                        mFlags |= kFlagSawMediaServerDie;
127352dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                        mFlags &= ~kFlagIsComponentAllocated;
1274aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    }
1275aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
12765530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    bool sendErrorResponse = true;
12775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12785778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    switch (mState) {
12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case INITIALIZING:
12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            setState(UNINITIALIZED);
12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case CONFIGURING:
12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1287c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1288c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : INITIALIZED);
12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
12915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTING:
12935778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
1294c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                            setState(actionCode == ACTION_CODE_FATAL ?
1295c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia                                    UNINITIALIZED : CONFIGURED);
12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1299c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                        case RELEASING:
13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            // Ignore the error, assuming we'll still get
13025d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                            // the shutdown complete notification. If we
13035d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                            // don't, we'll timeout and force release.
13045530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
13055d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                        }
13065d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                        // fall-thru
13075d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                        case STOPPING:
13085d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                        {
1309aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                            if (mFlags & kFlagSawMediaServerDie) {
131003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // MediaServer died, there definitely won't
131103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // be a shutdown complete notification after
131203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // all.
131303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber
131403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // note that we're directly going from
131503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // STOPPING->UNINITIALIZED, instead of the
131603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                // usual STOPPING->INITIALIZED state.
131703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                setState(UNINITIALIZED);
13186e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                if (mState == RELEASING) {
13196e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                    mComponentName.clear();
13206e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                                }
132103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                                (new AMessage)->postReply(mReplyID);
13225d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                                sendErrorResponse = false;
132303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                            }
13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case FLUSHING:
13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
13299e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            if (actionCode == ACTION_CODE_FATAL) {
13309e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(UNINITIALIZED);
13319e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            } else {
13329e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                setState(
13339e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                                        (mFlags & kFlagIsAsync) ? FLUSHED : STARTED);
13349e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen                            }
13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
13365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13380e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        case FLUSHED:
13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        case STARTED:
13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
13415530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1343251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1344575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            cancelPendingDequeueOperations();
1347c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1348c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1349251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1350251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1351251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1352251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1353251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1354251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1355251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1356251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1357251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1358251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1359251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1360c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
13625778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13635778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13645778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        default:
13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        {
13665530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                            sendErrorResponse = false;
13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1368251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1369575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1370c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1371251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            // actionCode in an uninitialized state is always fatal.
1372251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            if (mState == UNINITIALIZED) {
1373251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                actionCode = ACTION_CODE_FATAL;
1374251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1375c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            if (mFlags & kFlagIsAsync) {
1376251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                onError(err, actionCode);
1377251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            }
1378251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            switch (actionCode) {
1379251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_TRANSIENT:
1380251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1381251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            case ACTION_CODE_RECOVERABLE:
1382251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(INITIALIZED);
1383251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1384251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            default:
1385251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                setState(UNINITIALIZED);
1386251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                                break;
1387c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            }
13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                            break;
13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        }
13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
13925530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (sendErrorResponse) {
1393251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                        PostReplyWithError(mReplyID, err);
13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
13965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
13975778822d86b0337407514b9372562b86edfa91cdAndreas Huber
139879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatComponentAllocated:
13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, INITIALIZING);
14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    setState(INITIALIZED);
140252dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags |= kFlagIsComponentAllocated;
14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1404717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    CHECK(msg->findString("componentName", &mComponentName));
14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1406717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.startsWith("OMX.google.")) {
14073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
14085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    } else {
14093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags &= ~kFlagUsesSoftwareRenderer;
14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1412ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                    MediaResource::Type resourceType;
1413717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                    if (mComponentName.endsWith(".secure")) {
14141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags |= kFlagIsSecure;
1415ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                        resourceType = MediaResource::kSecureCodec;
14161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    } else {
14171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                        mFlags &= ~kFlagIsSecure;
1418ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                        resourceType = MediaResource::kNonSecureCodec;
14191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    }
1420c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu
142158828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu                    if (mIsVideo) {
142258828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu                        // audio codec is currently ignored.
1423ea15fd29af81490311af9e12949b43524c39400eRonghua Wu                        addResource(resourceType, MediaResource::kVideoCodec, 1);
142458828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu                    }
14251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
143079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatComponentConfigured:
14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1432c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                    if (mState == UNINITIALIZED || mState == INITIALIZED) {
1433c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        // In case a kWhatError message came in and replied with error,
1434c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        // we log a warning and ignore.
1435c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        ALOGW("configure interrupted by error, current state %d", mState);
1436c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                        break;
1437c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung                    }
14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    CHECK_EQ(mState, CONFIGURING);
14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
14406507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    // reset input surface flag
14416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                    mHaveInputSurface = false;
14426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
1443e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("input-format", &mInputFormat));
1444e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    CHECK(msg->findMessage("output-format", &mOutputFormat));
1445b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                    ALOGV("[%s] configured as input format: %s, output format: %s",
1446b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            mComponentName.c_str(),
1447b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            mInputFormat->debugString(4).c_str(),
1448b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                            mOutputFormat->debugString(4).c_str());
14493a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    int32_t usingSwRenderer;
14503a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer)
14513a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                            && usingSwRenderer) {
14523a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                        mFlags |= kFlagUsesSoftwareRenderer;
14533a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    }
14542606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang                    setState(CONFIGURED);
14555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber
145979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatInputSurfaceCreated:
14607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
146192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to initiateCreateInputSurface()
14627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err = NO_ERROR;
14631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
14647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (!msg->findInt32("err", &err)) {
14657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        sp<RefBase> obj;
14667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        msg->findObject("input-surface", &obj);
1467b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        CHECK(msg->findMessage("input-format", &mInputFormat));
1468b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        CHECK(msg->findMessage("output-format", &mOutputFormat));
1469b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                        ALOGV("[%s] input surface created as input format: %s, output format: %s",
1470b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mComponentName.c_str(),
1471b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mInputFormat->debugString(4).c_str(),
1472b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar                                mOutputFormat->debugString(4).c_str());
14737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        CHECK(obj != NULL);
14747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setObject("input-surface", obj);
14756507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                        mHaveInputSurface = true;
14767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    } else {
14777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
14787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
14797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
14807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
14817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
14827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
148379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatInputSurfaceAccepted:
1484d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                {
14858f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                    // response to initiateSetInputSurface()
1486d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    status_t err = NO_ERROR;
1487d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    sp<AMessage> response = new AMessage();
1488d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    if (!msg->findInt32("err", &err)) {
1489addf2cbb120346ae42e78fa739245a353db5edadChong Zhang                        CHECK(msg->findMessage("input-format", &mInputFormat));
1490addf2cbb120346ae42e78fa739245a353db5edadChong Zhang                        CHECK(msg->findMessage("output-format", &mOutputFormat));
1491d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        mHaveInputSurface = true;
1492d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    } else {
1493d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        response->setInt32("err", err);
1494d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    }
1495d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    response->postReply(mReplyID);
1496d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                    break;
1497d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                }
1498d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
149979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatSignaledInputEOS:
15007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                {
150192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar                    // response to signalEndOfInputStream()
15021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<AMessage> response = new AMessage;
15037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    status_t err;
15047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    if (msg->findInt32("err", &err)) {
15057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                        response->setInt32("err", err);
15067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    }
15077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    response->postReply(mReplyID);
15087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                    break;
15097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                }
15107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
1511dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                case kWhatStartCompleted:
15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1513dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    CHECK_EQ(mState, STARTING);
1514dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    if (mIsVideo) {
1515dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                        addResource(
1516dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                                MediaResource::kGraphicMemory,
1517dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                                MediaResource::kUnspecifiedSubType,
1518dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                                getGraphicBufferSize());
1519fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim                    }
1520dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    setState(STARTED);
1521dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    (new AMessage)->postReply(mReplyID);
1522dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    break;
1523dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                }
1524fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim
1525dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                case kWhatOutputBuffersChanged:
1526dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                {
1527dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    mFlags |= kFlagOutputBuffersChanged;
1528dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    postActivityNotificationIfPossible();
15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
153279054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatOutputFramesRendered:
153390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                {
153490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    // ignore these in all states except running, and check that we have a
153590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    // notification set
153690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    if (mState == STARTED && mOnFrameRenderedNotification != NULL) {
153790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        sp<AMessage> notify = mOnFrameRenderedNotification->dup();
153890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        notify->setMessage("data", msg);
153990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                        notify->post();
154090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    }
154190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    break;
154290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
154390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
154479054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatFillThisBuffer:
15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexInput, msg);
15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1548c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1549c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1550c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexInput);
15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    if (!mCSD.empty()) {
15568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        ssize_t index = dequeuePortBuffer(kPortIndexInput);
15578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        CHECK_GE(index, 0);
15588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // If codec specific data had been specified as
15608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // part of the format in the call to configure and
15618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // if there's more csd left, we submit it here
15628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // clients only get access to input buffers once
15638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        // this data has been exhausted.
15648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        status_t err = queueCSDInputBuffer(index);
15668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
15678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        if (err != OK) {
15688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            ALOGE("queueCSDInputBuffer failed w/ error %d",
15698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                                  err);
15708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1571251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                            setStickyError(err);
1572575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                            postActivityNotificationIfPossible();
1573575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
15748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                            cancelPendingDequeueOperations();
15758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        }
15768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                        break;
15778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber                    }
15788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
1579c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
15806e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        if (!mHaveInputSurface) {
15813d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            if (mState == FLUSHED) {
15823d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                mHavePendingInputBuffers = true;
15833d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            } else {
15843d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                                onInputBufferAvailable();
15853d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                            }
15866e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                        }
1587c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueInputPending) {
15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueInputTimeoutGeneration;
15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueInputPending;
15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueInputReplyID = 0;
1593575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1594575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
159979054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatDrainThisBuffer:
16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    /* size_t index = */updateBuffers(kPortIndexOutput, msg);
16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1603c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    if (mState == FLUSHING
1604c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == STOPPING
1605c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                            || mState == RELEASING) {
16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        returnBuffersToCodecOnPort(kPortIndexOutput);
16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        break;
16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16107e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    sp<RefBase> obj;
16117e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    CHECK(msg->findObject("buffer", &obj));
16127e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim                    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1614fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                    if (mOutputFormat != buffer->format()) {
1615fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                        mOutputFormat = buffer->format();
1616fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                        ALOGV("[%s] output format changed to: %s",
1617fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                mComponentName.c_str(), mOutputFormat->debugString(4).c_str());
1618fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim
1619fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                        if (mSoftRenderer == NULL &&
1620fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                mSurface != NULL &&
1621fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                (mFlags & kFlagUsesSoftwareRenderer)) {
1622fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            AString mime;
1623fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            CHECK(mOutputFormat->findString("mime", &mime));
1624fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim
1625fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            // TODO: propagate color aspects to software renderer to allow better
1626fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            // color conversion to RGB. For now, just mark dataspace for YUV
1627fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            // rendering.
1628fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            int32_t dataSpace;
1629fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) {
1630fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                ALOGD("[%s] setting dataspace on output surface to #%x",
1631fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                        mComponentName.c_str(), dataSpace);
1632fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                int err = native_window_set_buffers_data_space(
1633fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                        mSurface.get(), (android_dataspace)dataSpace);
1634fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                ALOGW_IF(err != 0, "failed to set dataspace on surface (%d)", err);
1635fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            }
1636fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim
1637fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            if (mime.startsWithIgnoreCase("video/")) {
1638fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
1639fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            }
1640fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                        }
16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
1642fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                        if (mFlags & kFlagIsEncoder) {
1643fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            // Before we announce the format change we should
1644fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            // collect codec specific data and amend the output
1645fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            // format as necessary.
1646dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                            int32_t flags = 0;
1647dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                            (void) buffer->meta()->findInt32("flags", &flags);
1648dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                            if (flags & BUFFER_FLAG_CODECCONFIG) {
1649fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                status_t err =
1650fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                    amendOutputFormatWithCodecSpecificData(buffer);
1651fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim
1652fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                if (err != OK) {
1653fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                    ALOGE("Codec spit out malformed codec "
1654fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                          "specific data!");
1655fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                }
1656e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                            }
1657e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                        }
1658e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1659c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        if (mFlags & kFlagIsAsync) {
1660c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            onOutputFormatChanged();
1661c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        } else {
1662c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                            mFlags |= kFlagOutputFormatChanged;
1663fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            postActivityNotificationIfPossible();
1664fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                        }
1665fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim
1666fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                        // Notify mCrypto of video resolution changes
1667fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                        if (mCrypto != NULL) {
1668fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            int32_t left, top, right, bottom, width, height;
1669fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) {
1670fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                mCrypto->notifyResolution(right - left + 1, bottom - top + 1);
1671fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            } else if (mOutputFormat->findInt32("width", &width)
1672fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                    && mOutputFormat->findInt32("height", &height)) {
1673fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                                mCrypto->notifyResolution(width, height);
1674fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                            }
1675c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        }
1676e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                    }
1677e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
1678c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    if (mFlags & kFlagIsAsync) {
1679c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                        onOutputBufferAvailable();
1680c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    } else if (mFlags & kFlagDequeueOutputPending) {
16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID));
16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber
16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        ++mDequeueOutputTimeoutGeneration;
16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mFlags &= ~kFlagDequeueOutputPending;
16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        mDequeueOutputReplyID = 0;
1686575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    } else {
1687575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                        postActivityNotificationIfPossible();
16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    }
1689575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber
169379054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatEOS:
16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // We already notify the client of this by using the
16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    // corresponding flag in "onOutputBufferReady".
16975778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
16985778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
16995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
170079054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatStopCompleted:
17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
1702349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                    if (mState != STOPPING) {
1703349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                        ALOGW("Received kWhatStopCompleted in state %d", mState);
17045d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                        break;
17055d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                    }
1706349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                    setState(INITIALIZED);
1707349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                    (new AMessage)->postReply(mReplyID);
1708349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                    break;
1709349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                }
1710349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang
171179054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatReleaseCompleted:
1712349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                {
1713349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                    if (mState != RELEASING) {
1714349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                        ALOGW("Received kWhatReleaseCompleted in state %d", mState);
1715349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                        break;
1716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                    }
1717349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                    setState(UNINITIALIZED);
1718349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang                    mComponentName.clear();
1719349b8b4c47817a565ded94ff351caf48782f1252Chong Zhang
172052dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                    mFlags &= ~kFlagIsComponentAllocated;
17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
172267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu                    mResourceManagerService->removeResource(getId(mResourceManagerClient));
172367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
172879054b1f53b448511f1edb6e0dcab1d7b6f39964Wonsik Kim                case kWhatFlushCompleted:
17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber                {
17305530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    if (mState != FLUSHING) {
17315530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        ALOGW("received FlushCompleted message in state %d",
17325530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                                mState);
17335530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                        break;
17345530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia                    }
17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17360e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    if (mFlags & kFlagIsAsync) {
17370e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(FLUSHED);
17380e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    } else {
17390e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        setState(STARTED);
17400e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                        mCodec->signalResume();
17410e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    }
17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    (new AMessage)->postReply(mReplyID);
17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    break;
17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber                default:
17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    TRESPASS();
17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatInit:
17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
17553f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != UNINITIALIZED) {
1759c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(INITIALIZING);
17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber            AString name;
17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findString("name", &name));
17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t nameIsType;
17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t encoder = false;
17710db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            CHECK(msg->findInt32("nameIsType", &nameIsType));
17720db280176bd3277e3256252d063f3712b1905ba9Andreas Huber            if (nameIsType) {
17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber                CHECK(msg->findInt32("encoder", &encoder));
17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format = new AMessage;
17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (nameIsType) {
17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("mime", name.c_str());
17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", encoder);
17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setString("componentName", name.c_str());
17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber
17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateAllocateComponent(format);
17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
178990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        case kWhatSetNotification:
179090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        {
179190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            sp<AMessage> notify;
179290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            if (msg->findMessage("on-frame-rendered", &notify)) {
179390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                mOnFrameRenderedNotification = notify;
179490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            }
179590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            break;
179690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
179790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
1798c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        case kWhatSetCallback:
1799c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        {
18003f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
1801c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->senderAwaitsResponse(&replyID));
1802c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1803c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mState == UNINITIALIZED
1804c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    || mState == INITIALIZING
18050e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    || isExecuting()) {
18060e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                // callback can't be set after codec is executing,
1807c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // or before it's initialized (as the callback
1808c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                // will be cleared when it goes to INITIALIZED)
1809c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
1810c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
1811c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1812c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1813c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> callback;
1814c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            CHECK(msg->findMessage("callback", &callback));
1815c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1816c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            mCallback = callback;
1817c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1818c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mCallback != NULL) {
1819c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGI("MediaCodec will operate in async mode");
1820c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags |= kFlagIsAsync;
1821c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            } else {
1822c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                mFlags &= ~kFlagIsAsync;
1823c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
1824c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
1825c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            sp<AMessage> response = new AMessage;
1826c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            response->postReply(replyID);
1827c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            break;
1828c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        }
1829c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatConfigure:
18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
18323f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (mState != INITIALIZED) {
1836c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<RefBase> obj;
1841f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar            CHECK(msg->findObject("surface", &obj));
18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> format;
18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findMessage("format", &format));
18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18468b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            int32_t push;
18478b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) {
18488b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                mFlags |= kFlagPushBlankBuffersOnShutdown;
18498b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
18508b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (obj != NULL) {
18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setObject("native-window", obj);
1853f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                status_t err = handleSetSurface(static_cast<Surface *>(obj.get()));
18547541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                if (err != OK) {
1855c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                    PostReplyWithError(replyID, err);
18567541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber                    break;
18571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
18581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
1859f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar                handleSetSurface(NULL);
18601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            }
18611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
18627541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            mReplyID = replyID;
18637541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber            setState(CONFIGURING);
18647541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
18651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *crypto;
18661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!msg->findPointer("crypto", &crypto)) {
18671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                crypto = NULL;
18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            mCrypto = static_cast<ICrypto *>(crypto);
1871dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mBufferChannel->setCrypto(mCrypto);
18721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber            uint32_t flags;
18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("flags", (int32_t *)&flags));
18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags & CONFIGURE_FLAG_ENCODE) {
18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber                format->setInt32("encoder", true);
1878e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber                mFlags |= kFlagIsEncoder;
18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            extractCSD(format);
18828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateConfigureComponent(format);
18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber
18871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        case kWhatSetSurface:
18881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        {
18891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<AReplyToken> replyID;
18901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            CHECK(msg->senderAwaitsResponse(&replyID));
18911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
18921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            status_t err = OK;
18931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            sp<Surface> surface;
18941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
18951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            switch (mState) {
18961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case CONFIGURED:
18971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case STARTED:
18981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                case FLUSHED:
18991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                {
19001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<RefBase> obj;
19011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    (void)msg->findObject("surface", &obj);
19021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    sp<Surface> surface = static_cast<Surface *>(obj.get());
19031dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    if (mSurface == NULL) {
19041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support setting surface if it was not set
19051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = INVALID_OPERATION;
19061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else if (obj == NULL) {
19071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        // do not support unsetting surface
19081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = BAD_VALUE;
19091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    } else {
19101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        err = connectToSurface(surface);
1911098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar                        if (err == ALREADY_EXISTS) {
1912098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar                            // reconnecting to same surface
19131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            err = OK;
19141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        } else {
19151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
19161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                if (mFlags & kFlagUsesSoftwareRenderer) {
19178b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    if (mSoftRenderer != NULL
19188b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                            && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
19198b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                        pushBlankBuffersToNativeWindow(mSurface.get());
19208b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                                    }
19211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    mSoftRenderer = new SoftwareRenderer(surface);
19221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    // TODO: check if this was successful
19231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                } else {
19241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                    err = mCodec->setSurface(surface);
19251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                }
19261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
19271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            if (err == OK) {
19281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                (void)disconnectFromSurface();
19291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                                mSurface = surface;
19301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                            }
19311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                        }
19321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    }
19331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
19341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                }
19351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
19361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                default:
19371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    err = INVALID_OPERATION;
19381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar                    break;
19391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
19401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
19411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            PostReplyWithError(replyID, err);
19421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            break;
19431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
19441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
19457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatCreateInputSurface:
19468f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang        case kWhatSetInputSurface:
19477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
19483f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
19507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
19517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            // Must be configured, but can't have been started yet.
19527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            if (mState != CONFIGURED) {
1953c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
19557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
19567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
19577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
1958d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            if (msg->what() == kWhatCreateInputSurface) {
1959d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                mCodec->initiateCreateInputSurface();
1960d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            } else {
1961d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                sp<RefBase> obj;
1962d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                CHECK(msg->findObject("input-surface", &obj));
1963d291c222357303b9611cab89d0c3b047584ef377Chong Zhang
19648f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                mCodec->initiateSetInputSurface(
1965d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                        static_cast<PersistentSurface *>(obj.get()));
1966d291c222357303b9611cab89d0c3b047584ef377Chong Zhang            }
19677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
19687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStart:
19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
19713f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            if (mState == FLUSHED) {
1975d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                setState(STARTED);
19763d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                if (mHavePendingInputBuffers) {
19773d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    onInputBufferAvailable();
19783d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                    mHavePendingInputBuffers = false;
19793d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang                }
19800e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                mCodec->signalResume();
19810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                PostReplyWithError(replyID, OK);
1982d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang                break;
19830e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            } else if (mState != CONFIGURED) {
1984c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(STARTING);
19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->initiateStart();
19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatStop:
1996c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        case kWhatRelease:
1997c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        {
1998aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            State targetState =
1999aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED;
2000aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
20013f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2002c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2003c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
200447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            // already stopped/released
200547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (mState == UNINITIALIZED && mReleasedByResourceManager) {
200647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                sp<AMessage> response = new AMessage;
200747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->setInt32("err", OK);
200847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                response->postReply(replyID);
200947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                break;
201047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
201147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
201247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            int32_t reclaimed = 0;
201347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            msg->findInt32("reclaimed", &reclaimed);
201447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            if (reclaimed) {
201547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                mReleasedByResourceManager = true;
20164b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
20174b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                int32_t force = 0;
20184b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                msg->findInt32("force", &force);
20194b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                if (!force && hasPendingBuffer()) {
20204b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    ALOGW("Can't reclaim codec right now due to pending buffers.");
20214b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
20224b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    // return WOULD_BLOCK to ask resource manager to retry later.
20234b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    sp<AMessage> response = new AMessage;
20244b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    response->setInt32("err", WOULD_BLOCK);
20254b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    response->postReply(replyID);
20264b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu
20274b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    // notify the async client
20284b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    if (mFlags & kFlagIsAsync) {
20294b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                        onError(DEAD_OBJECT, ACTION_CODE_FATAL);
20304b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    }
20314b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                    break;
20324b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu                }
203347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu            }
203447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu
20355d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            bool isReleasingAllocatedComponent =
20365d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                    (mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED;
20375d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            if (!isReleasingAllocatedComponent // See 1
203833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                    && mState != INITIALIZED
20390e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                    && mState != CONFIGURED && !isExecuting()) {
204033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 1) Permit release to shut down the component if allocated.
204133223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                //
204233223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung                // 2) We may be in "UNINITIALIZED" state already and
204352dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                // also shutdown the encoder/decoder without the
204403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // client being aware of this if media server died while
204503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // we were being stopped. The client would assume that
204603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // after stop() returned, it would be safe to call release()
204703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // and it should be in this case, no harm to allow a release()
204803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber                // if we're already uninitialized.
2049c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                sp<AMessage> response = new AMessage;
205047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // TODO: we shouldn't throw an exception for stop/release. Change this to wait until
205147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu                // the previous stop/release completes and then reply with OK.
20526e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                status_t err = mState == targetState ? OK : INVALID_OPERATION;
20536e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                response->setInt32("err", err);
20546e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (err == OK && targetState == UNINITIALIZED) {
20556e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
20566e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
2057c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                response->postReply(replyID);
2058c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                break;
2059c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            }
2060c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
20615d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            // If we're flushing, or we're stopping but received a release
20625d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            // request, post the reply for the pending call first, and consider
20635d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            // it done. The reply token will be replaced after this, and we'll
20645d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            // no longer be able to reply.
20655d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            if (mState == FLUSHING || mState == STOPPING) {
20665d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                (new AMessage)->postReply(mReplyID);
20675d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            }
20685d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang
2069aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            if (mFlags & kFlagSawMediaServerDie) {
2070aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // It's dead, Jim. Don't expect initiateShutdown to yield
2071aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                // any useful results now...
2072aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                setState(UNINITIALIZED);
20736e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                if (targetState == UNINITIALIZED) {
20746e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                    mComponentName.clear();
20756e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar                }
2076aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                (new AMessage)->postReply(replyID);
2077aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                break;
2078aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            }
2079aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
20805d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            // If we already have an error, component may not be able to
20815d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            // complete the shutdown properly. If we're stopping, post the
20825d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            // reply now with an error to unblock the client, client can
20835d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            // release after the failure (instead of ANR).
20845d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            if (msg->what() == kWhatStop && (mFlags & kFlagStickyError)) {
20855d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                PostReplyWithError(replyID, getStickyError());
20865d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang                break;
20875d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang            }
20885d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang
2089c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber            mReplyID = replyID;
2090aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            setState(msg->what() == kWhatStop ? STOPPING : RELEASING);
2091aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber
2092aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber            mCodec->initiateShutdown(
2093aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                    msg->what() == kWhatStop /* keepComponentAllocated */);
2094c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber
209586b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu            returnBuffersToCodec(reclaimed);
20968b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar
20978b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) {
20988b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                pushBlankBuffersToNativeWindow(mSurface.get());
20998b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar            }
21005d552fb812bebc3f15c7fe91a3e315a97e3ffb34Chong Zhang
21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputBuffer:
21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
21063f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2109c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
2110c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
2111c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2112c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
2113c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
2114c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
21156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            if (mHaveInputSurface) {
21166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                ALOGE("dequeueInputBuffer can't be used with input surface");
2117c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21186507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden                break;
21196507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden            }
21206507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden
21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueInputBuffer(replyID, true /* new request */)) {
21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
2129c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueInputPending;
21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = replyID;
21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
21381d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueInputTimedOut, this);
21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueInputTimeoutGeneration);
21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueInputTimedOut:
21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueInputTimeoutGeneration) {
21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueInputPending);
21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2158c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueInputReplyID, -EAGAIN);
21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueInputPending;
21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueInputReplyID = 0;
21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatQueueInputBuffer:
21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
21673f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2170251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2171c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2173251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2174251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2175251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onQueueInputBuffer(msg);
21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2180c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputBuffer:
21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
21863f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2189c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            if (mFlags & kFlagIsAsync) {
2190c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                ALOGE("dequeueOutputBuffer can't be used in async mode");
2191c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2192c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                break;
2193c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            }
2194c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (handleDequeueOutputBuffer(replyID, true /* new request */)) {
21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber
21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int64_t timeoutUs;
22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt64("timeoutUs", &timeoutUs));
22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs == 0ll) {
2203c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, -EAGAIN);
22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags |= kFlagDequeueOutputPending;
22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = replyID;
22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (timeoutUs > 0ll) {
22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber                sp<AMessage> timeoutMsg =
22121d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar                    new AMessage(kWhatDequeueOutputTimedOut, this);
22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->setInt32(
22145778822d86b0337407514b9372562b86edfa91cdAndreas Huber                        "generation", ++mDequeueOutputTimeoutGeneration);
22155778822d86b0337407514b9372562b86edfa91cdAndreas Huber                timeoutMsg->post(timeoutUs);
22165778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22205778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatDequeueOutputTimedOut:
22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t generation;
22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("generation", &generation));
22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (generation != mDequeueOutputTimeoutGeneration) {
22265778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // Obsolete
22275778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
22285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22295778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22305778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(mFlags & kFlagDequeueOutputPending);
22315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2232c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(mDequeueOutputReplyID, -EAGAIN);
22335778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mFlags &= ~kFlagDequeueOutputPending;
22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mDequeueOutputReplyID = 0;
22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatReleaseOutputBuffer:
22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
22413f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2244251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2245c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2247251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2248251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2249251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            status_t err = onReleaseOutputBuffer(msg);
22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2254c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        case kWhatSignalEndOfInputStream:
22597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        {
22603f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
22617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            CHECK(msg->senderAwaitsResponse(&replyID));
22627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
22636d332d2cdf6e62c2c20ebff220868fe9e3ed7f44Chong Zhang            if (!isExecuting() || !mHaveInputSurface) {
2264c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
22657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                break;
2266251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2267251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2268251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
22697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
22707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
22717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mReplyID = replyID;
22727cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            mCodec->signalEndOfInputStream();
22737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            break;
22747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden        }
22757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetBuffers:
22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
22783f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
228029b7dcf6d3cdb97103467dc8106151c6260c239aJeff Tinker            if (!isExecuting() || (mFlags & kFlagIsAsync)) {
2281c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
22825778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2283251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2284251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2285251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
22865778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
22875778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber            int32_t portIndex;
22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findInt32("portIndex", &portIndex));
22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22917e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim            Vector<sp<MediaCodecBuffer> > *dstBuffers;
22925778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->findPointer("buffers", (void **)&dstBuffers));
22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber
22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber            dstBuffers->clear();
2295e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang            // If we're using input surface (either non-persistent created by
2296e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang            // createInputSurface(), or persistent set by setInputSurface()),
2297e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang            // give the client an empty input buffers array.
2298e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang            if (portIndex != kPortIndexInput || !mHaveInputSurface) {
2299dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                if (portIndex == kPortIndexInput) {
2300dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    mBufferChannel->getInputBufferArray(dstBuffers);
2301dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                } else {
2302dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    mBufferChannel->getOutputBufferArray(dstBuffers);
2303e4aab10641a099d8a295b3ed61e2f5248f28a669Chong Zhang                }
23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber            (new AMessage)->postReply(replyID);
23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatFlush:
23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
23123f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2315251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            if (!isExecuting()) {
2316c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2318251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2319251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2320251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mReplyID = replyID;
23240e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar            // TODO: skip flushing if already FLUSHED
23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber            setState(FLUSHING);
23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber            mCodec->signalFlush();
23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber            returnBuffersToCodec();
23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2332e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar        case kWhatGetInputFormat:
23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        case kWhatGetOutputFormat:
23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        {
2335e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            sp<AMessage> format =
2336e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat);
2337e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar
23383f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2341e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if ((mState != CONFIGURED && mState != STARTING &&
23420e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != STARTED && mState != FLUSHING &&
23430e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar                 mState != FLUSHED)
2344e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar                    || format == NULL) {
2345c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber                break;
2347251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung            } else if (mFlags & kFlagStickyError) {
2348251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                PostReplyWithError(replyID, getStickyError());
2349251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung                break;
23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber
23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            sp<AMessage> response = new AMessage;
2353e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            response->setMessage("format", format);
23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber            response->postReply(replyID);
23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber            break;
23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2358496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        case kWhatRequestIDRFrame:
2359496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        {
2360496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            mCodec->signalRequestIDRFrame();
2361496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            break;
2362496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        }
2363496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber
2364575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        case kWhatRequestActivityNotification:
2365575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        {
2366575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(mActivityNotify == NULL);
2367575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            CHECK(msg->findMessage("notify", &mActivityNotify));
2368575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2369575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            postActivityNotificationIfPossible();
2370575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            break;
2371575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
2372575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2373717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        case kWhatGetName:
2374717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        {
23753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2376717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            CHECK(msg->senderAwaitsResponse(&replyID));
2377717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2378717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            if (mComponentName.empty()) {
2379c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                PostReplyWithError(replyID, INVALID_OPERATION);
2380717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                break;
2381717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
2382717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2383717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            sp<AMessage> response = new AMessage;
2384717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->setString("name", mComponentName.c_str());
2385717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            response->postReply(replyID);
2386717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            break;
2387717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo        }
2388717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2389a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        case kWhatSetParameters:
2390a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        {
23913f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar            sp<AReplyToken> replyID;
2392a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->senderAwaitsResponse(&replyID));
2393a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2394a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            sp<AMessage> params;
2395a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            CHECK(msg->findMessage("params", &params));
2396a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2397a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            status_t err = onSetParameters(params);
2398a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2399c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang            PostReplyWithError(replyID, err);
2400a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            break;
2401a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        }
2402a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        default:
24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber            TRESPASS();
24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24065778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24088ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) {
24098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.clear();
24108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    size_t i = 0;
24128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    for (;;) {
24138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        sp<ABuffer> csd;
2414a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes        if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
24158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber            break;
24168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        }
24174f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang        if (csd->size() == 0) {
24184f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang            ALOGW("csd-%zu size is 0", i);
24194f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang        }
24208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        mCSD.push_back(csd);
24228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        ++i;
24238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
24248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2425a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Found %zu pieces of codec specific data.", mCSD.size());
24268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
24278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) {
24298ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    CHECK(!mCSD.empty());
24308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2431dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    const BufferInfo &info = mPortBuffers[kPortIndexInput][bufferIndex];
24328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    sp<ABuffer> csd = *mCSD.begin();
24348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    mCSD.erase(mCSD.begin());
24358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
2436dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    const sp<MediaCodecBuffer> &codecInputData = info.mData;
24378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    if (csd->size() > codecInputData->capacity()) {
24398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return -EINVAL;
24408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
24418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    memcpy(codecInputData->data(), csd->data(), csd->size());
24438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    AString errorDetailMsg;
24458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this);
24478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("index", bufferIndex);
24488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("offset", 0);
24498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setSize("size", csd->size());
24508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt64("timeUs", 0ll);
24518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG);
24528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    msg->setPointer("errorDetailMsg", &errorDetailMsg);
24538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    return onQueueInputBuffer(msg);
24558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber}
24568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber
24575778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) {
24587541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    if (newState == INITIALIZED || newState == UNINITIALIZED) {
24595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        delete mSoftRenderer;
24605778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mSoftRenderer = NULL;
24615778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        mCrypto.clear();
2463f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        handleSetSurface(NULL);
24645778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2465671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        mInputFormat.clear();
24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mOutputFormat.clear();
24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputFormatChanged;
24685778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagOutputBuffersChanged;
24695778822d86b0337407514b9372562b86edfa91cdAndreas Huber        mFlags &= ~kFlagStickyError;
2470e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        mFlags &= ~kFlagIsEncoder;
2471c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mFlags &= ~kFlagIsAsync;
2472251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        mStickyError = OK;
2473575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2474575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2475c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        mCallback.clear();
24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2478717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    if (newState == UNINITIALIZED) {
2479671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        // return any straggling buffers, e.g. if we got here on an error
2480671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        returnBuffersToCodec();
2481671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
2482aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // The component is gone, mediaserver's probably back up already
2483aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // but should definitely be back up should we try to instantiate
2484aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        // another component.. and the cycle continues.
2485aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber        mFlags &= ~kFlagSawMediaServerDie;
2486717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo    }
2487717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mState = newState;
24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber    cancelPendingDequeueOperations();
24912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
24922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    updateBatteryStat();
24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber
249586b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wuvoid MediaCodec::returnBuffersToCodec(bool isReclaim) {
249686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    returnBuffersToCodecOnPort(kPortIndexInput, isReclaim);
249786b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    returnBuffersToCodecOnPort(kPortIndexOutput, isReclaim);
24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber
250086b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wuvoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim) {
25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
25027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    Mutex::Autolock al(mBufferLock);
25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2504dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    for (size_t i = 0; i < mPortBuffers[portIndex].size(); ++i) {
2505dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        BufferInfo *info = &mPortBuffers[portIndex][i];
25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2507dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        if (info->mData != nullptr) {
2508dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            sp<MediaCodecBuffer> buffer = info->mData;
250986b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu            if (isReclaim && info->mOwnedByClient) {
251086b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu                ALOGD("port %d buffer %zu still owned by client when codec is reclaimed",
251186b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu                        portIndex, i);
251286b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu            } else {
251386b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu                info->mOwnedByClient = false;
2514fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim                info->mData.clear();
25155778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2516dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mBufferChannel->discardBuffer(buffer);
25175778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
25185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
25195778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25205778822d86b0337407514b9372562b86edfa91cdAndreas Huber    mAvailPortBuffers[portIndex].clear();
25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25235778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers(
25245778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int32_t portIndex, const sp<AMessage> &msg) {
25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
2526dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    size_t index;
2527dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    CHECK(msg->findSize("index", &index));
2528fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    sp<RefBase> obj;
2529fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    CHECK(msg->findObject("buffer", &obj));
2530fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2532dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    {
2533dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        Mutex::Autolock al(mBufferLock);
2534dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        if (mPortBuffers[portIndex].size() <= index) {
2535dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mPortBuffers[portIndex].resize(align(index + 1, kNumBuffersAlign));
25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2537dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mPortBuffers[portIndex][index].mData = buffer;
25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
2539dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    mAvailPortBuffers[portIndex].push_back(index);
25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2541dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    return index;
25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t offset;
25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t size;
25485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int64_t timeUs;
25495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    uint32_t flags;
25505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
25515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("offset", &offset));
25525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt64("timeUs", &timeUs));
25535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findInt32("flags", (int32_t *)&flags));
25545778822d86b0337407514b9372562b86edfa91cdAndreas Huber
25554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const CryptoPlugin::SubSample *subSamples;
25564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    size_t numSubSamples;
25574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *key;
25584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    const uint8_t *iv;
25594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted;
25604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
25614b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // We allow the simpler queueInputBuffer API to be used even in
25624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    // secure mode, by fabricating a single unencrypted subSample.
25634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    CryptoPlugin::SubSample ss;
2564d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker    CryptoPlugin::Pattern pattern;
25654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
25664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    if (msg->findSize("size", &size)) {
25674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto != NULL) {
25684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfClearData = size;
25694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            ss.mNumBytesOfEncryptedData = 0;
25704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
25714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            subSamples = &ss;
25724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            numSubSamples = 1;
25734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = NULL;
25744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = NULL;
2575d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker            pattern.mEncryptBlocks = 0;
2576d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker            pattern.mSkipBlocks = 0;
25774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
25784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    } else {
25794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (mCrypto == NULL) {
25804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            return -EINVAL;
25814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
25824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
25834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("subSamples", (void **)&subSamples));
25844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findSize("numSubSamples", &numSubSamples));
25854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("key", (void **)&key));
25864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findPointer("iv", (void **)&iv));
2587d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker        CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
2588d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker        CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
25894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
25904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int32_t tmp;
25914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        CHECK(msg->findInt32("mode", &tmp));
25924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
25934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        mode = (CryptoPlugin::Mode)tmp;
25944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
25954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        size = 0;
25964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
25974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfClearData;
25984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            size += subSamples[i].mNumBytesOfEncryptedData;
25994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
26004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber    }
26014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexInput].size()) {
26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26055778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2606dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    BufferInfo *info = &mPortBuffers[kPortIndexInput][index];
26075778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2608dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (info->mData == nullptr || !info->mOwnedByClient) {
26095778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
26105778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26115778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (offset + size > info->mData->capacity()) {
26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
26145778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26155778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26165778822d86b0337407514b9372562b86edfa91cdAndreas Huber    info->mData->setRange(offset, size);
2617dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    info->mData->meta()->setInt64("timeUs", timeUs);
2618dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (flags & BUFFER_FLAG_EOS) {
2619dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        info->mData->meta()->setInt32("eos", true);
2620dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
26215778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2622dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (flags & BUFFER_FLAG_CODECCONFIG) {
2623dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        info->mData->meta()->setInt32("csd", true);
2624dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
2625dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim
2626dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    // synchronization boundary for getBufferAndFormat
2627dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    sp<MediaCodecBuffer> buffer;
2628dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    {
2629dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        Mutex::Autolock al(mBufferLock);
2630dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        info->mOwnedByClient = false;
2631dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        buffer = info->mData;
2632dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        info->mData.clear();
2633dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    }
2634dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    status_t err = OK;
26351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    if (mCrypto != NULL) {
26365b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        AString *errorDetailMsg;
26375b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
26385b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2639dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        err = mBufferChannel->queueSecureInputBuffer(
2640dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                buffer,
2641dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                (mFlags & kFlagIsSecure),
26421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                key,
26431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                iv,
26441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                mode,
264518cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker                pattern,
26464b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                subSamples,
26474b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber                numSubSamples,
26485b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                errorDetailMsg);
2649dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    } else {
2650dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        err = mBufferChannel->queueInputBuffer(buffer);
2651fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim    }
2652fad01bc45bd47b8f12c89857fee20b7e37310125Wonsik Kim
2653dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    return err;
26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber
265690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar//static
265790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarsize_t MediaCodec::CreateFramesRenderedMessage(
26580d1ed381fde5dac12dd84fcf3da66dac46699378Chih-Hung Hsieh        const std::list<FrameRenderTracker::Info> &done, sp<AMessage> &msg) {
265990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    size_t index = 0;
266090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
266190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin();
266290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            it != done.cend(); ++it) {
266390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if (it->getRenderTimeNs() < 0) {
266490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            continue; // dropped frame from tracking
266590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
266690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->setInt64(AStringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs());
266790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        msg->setInt64(AStringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs());
266890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        ++index;
266990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
267090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return index;
267190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
267290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
26735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
26745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index;
26755778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(msg->findSize("index", &index));
26765778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26775778822d86b0337407514b9372562b86edfa91cdAndreas Huber    int32_t render;
26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (!msg->findInt32("render", &render)) {
26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber        render = 0;
26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26820e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar    if (!isExecuting()) {
26835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EINVAL;
26845778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26855778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26865778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (index >= mPortBuffers[kPortIndexOutput].size()) {
26875778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -ERANGE;
26885778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26895778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2690dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    BufferInfo *info = &mPortBuffers[kPortIndexOutput][index];
26915778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2692dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (info->mData == nullptr || !info->mOwnedByClient) {
26935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EACCES;
26945778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
26955778822d86b0337407514b9372562b86edfa91cdAndreas Huber
26967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    // synchronization boundary for getBufferAndFormat
2697dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    sp<MediaCodecBuffer> buffer;
26987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
26997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
27007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = false;
2701dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        buffer = info->mData;
2702dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        info->mData.clear();
27037bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
27047bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
2705dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    if (render && buffer->size() != 0) {
270690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t mediaTimeUs = -1;
2707dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        buffer->meta()->findInt64("timeUs", &mediaTimeUs);
270890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
270990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        int64_t renderTimeNs = 0;
2710c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar        if (!msg->findInt64("timestampNs", &renderTimeNs)) {
2711c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            // use media timestamp if client did not request a specific render timestamp
2712c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar            ALOGV("using buffer PTS of %lld", (long long)mediaTimeUs);
271390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            renderTimeNs = mediaTimeUs * 1000;
2714fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar        }
2715fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar
27165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (mSoftRenderer != NULL) {
271790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            std::list<FrameRenderTracker::Info> doneFrames = mSoftRenderer->render(
2718dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    buffer->data(), buffer->size(),
2719dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim                    mediaTimeUs, renderTimeNs, NULL, buffer->format());
272090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
272190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            // if we are running, notify rendered frames
272290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            if (!doneFrames.empty() && mState == STARTED && mOnFrameRenderedNotification != NULL) {
272390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                sp<AMessage> notify = mOnFrameRenderedNotification->dup();
272490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                sp<AMessage> data = new AMessage;
272590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                if (CreateFramesRenderedMessage(doneFrames, data)) {
272690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    notify->setMessage("data", data);
272790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    notify->post();
272890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                }
272990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            }
27305778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2731dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->renderOutputBuffer(buffer, renderTimeNs);
2732dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    } else {
2733dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        mBufferChannel->discardBuffer(buffer);
27345778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27355778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27365778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return OK;
27375778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27385778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27395778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) {
27405778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
27415778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27425778822d86b0337407514b9372562b86edfa91cdAndreas Huber    List<size_t> *availBuffers = &mAvailPortBuffers[portIndex];
27435778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27445778822d86b0337407514b9372562b86edfa91cdAndreas Huber    if (availBuffers->empty()) {
27455778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return -EAGAIN;
27465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
27475778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    size_t index = *availBuffers->begin();
27495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    availBuffers->erase(availBuffers->begin());
27505778822d86b0337407514b9372562b86edfa91cdAndreas Huber
2751dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim    BufferInfo *info = &mPortBuffers[portIndex][index];
27525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CHECK(!info->mOwnedByClient);
27537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    {
27547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Mutex::Autolock al(mBufferLock);
27557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        info->mOwnedByClient = true;
275603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar
275703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        // set image-data
2758fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim        if (info->mData->format() != NULL) {
275903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            sp<ABuffer> imageData;
2760fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            if (info->mData->format()->findBuffer("image-data", &imageData)) {
276103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setBuffer("image-data", imageData);
276203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
276303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            int32_t left, top, right, bottom;
2764fd44d8e2f2d37184f7add67125657f3fbfb5a085Wonsik Kim            if (info->mData->format()->findRect("crop", &left, &top, &right, &bottom)) {
276503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar                info->mData->meta()->setRect("crop-rect", left, top, right, bottom);
276603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar            }
276703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar        }
27687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
27695778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    return index;
27715778822d86b0337407514b9372562b86edfa91cdAndreas Huber}
27725778822d86b0337407514b9372562b86edfa91cdAndreas Huber
27731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::connectToSurface(const sp<Surface> &surface) {
27741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
27751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (surface != NULL) {
2776b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar        uint64_t oldId, newId;
2777098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        if (mSurface != NULL
2778b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar                && surface->getUniqueId(&newId) == NO_ERROR
2779b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar                && mSurface->getUniqueId(&oldId) == NO_ERROR
2780b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar                && newId == oldId) {
2781b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar            ALOGI("[%s] connecting to the same surface. Nothing to do.", mComponentName.c_str());
2782098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar            return ALREADY_EXISTS;
2783098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        }
2784098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar
27851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2786098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar        if (err == OK) {
2787264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // Require a fresh set of buffers after each connect by using a unique generation
2788264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // number. Rely on the fact that max supported process id by Linux is 2^22.
2789264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // PID is never 0 so we don't have to worry that we use the default generation of 0.
2790264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // TODO: come up with a unique scheme if other producers also set the generation number.
2791264bac95912efe121d6a60026612617f04f42966Lajos Molnar            static uint32_t mSurfaceGeneration = 0;
2792264bac95912efe121d6a60026612617f04f42966Lajos Molnar            uint32_t generation = (getpid() << 10) | (++mSurfaceGeneration & ((1 << 10) - 1));
2793264bac95912efe121d6a60026612617f04f42966Lajos Molnar            surface->setGenerationNumber(generation);
2794264bac95912efe121d6a60026612617f04f42966Lajos Molnar            ALOGI("[%s] setting surface generation to %u", mComponentName.c_str(), generation);
2795264bac95912efe121d6a60026612617f04f42966Lajos Molnar
2796264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // HACK: clear any free buffers. Remove when connect will automatically do this.
2797264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // This is needed as the consumer may be holding onto stale frames that it can reattach
2798264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // to this surface after disconnect/connect, and those free frames would inherit the new
2799264bac95912efe121d6a60026612617f04f42966Lajos Molnar            // generation number. Disconnecting after setting a unique generation prevents this.
2800264bac95912efe121d6a60026612617f04f42966Lajos Molnar            native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2801264bac95912efe121d6a60026612617f04f42966Lajos Molnar            err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA);
2802264bac95912efe121d6a60026612617f04f42966Lajos Molnar        }
2803264bac95912efe121d6a60026612617f04f42966Lajos Molnar
2804264bac95912efe121d6a60026612617f04f42966Lajos Molnar        if (err != OK) {
28051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err);
28061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
28071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
2808098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    // do not return ALREADY_EXISTS unless surfaces are the same
2809098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar    return err == ALREADY_EXISTS ? BAD_VALUE : err;
28101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
28117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
28121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::disconnectFromSurface() {
28131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
2814f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (mSurface != NULL) {
2815264bac95912efe121d6a60026612617f04f42966Lajos Molnar        // Resetting generation is not technically needed, but there is no need to keep it either
2816264bac95912efe121d6a60026612617f04f42966Lajos Molnar        mSurface->setGenerationNumber(0);
28171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_MEDIA);
28187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        if (err != OK) {
28191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            ALOGW("native_window_api_disconnect returned an error: %s (%d)", strerror(-err), err);
28207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
28211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        // assume disconnected even on error
2822f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        mSurface.clear();
28237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
28241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
28251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar}
28267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
28271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::handleSetSurface(const sp<Surface> &surface) {
28281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    status_t err = OK;
28291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    if (mSurface != NULL) {
28301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        (void)disconnectFromSurface();
28311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    }
2832f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar    if (surface != NULL) {
28331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        err = connectToSurface(surface);
28341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        if (err == OK) {
28351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            mSurface = surface;
28367541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        }
28377541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber    }
28381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    return err;
28397541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber}
28407541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber
2841c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() {
2842c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2843c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) {
2844c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2845c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_INPUT_AVAILABLE);
2846c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2847c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2848c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2849c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2850c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2851c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() {
2852c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    int32_t index;
2853c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) {
28547e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        const sp<MediaCodecBuffer> &buffer =
2855dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim            mPortBuffers[kPortIndexOutput][index].mData;
2856c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2857c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE);
2858c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("index", index);
2859c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("offset", buffer->offset());
2860c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setSize("size", buffer->size());
2861c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2862c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        int64_t timeUs;
2863c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
2864c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2865c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt64("timeUs", timeUs);
2866c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2867dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        int32_t flags;
2868dff26e5f53b248fd8cc6605850240c7e7c5438dcWonsik Kim        CHECK(buffer->meta()->findInt32("flags", &flags));
2869c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2870c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("flags", flags);
2871c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2872c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2873c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2874c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2875c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2876749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) {
2877c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2878c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2879c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_ERROR);
2880c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("err", err);
2881749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        msg->setInt32("actionCode", actionCode);
2882749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang
2883749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        if (detail != NULL) {
2884749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang            msg->setString("detail", detail);
2885749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang        }
2886c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2887c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2888c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2889c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2890c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2891c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() {
2892c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    if (mCallback != NULL) {
2893c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        sp<AMessage> msg = mCallback->dup();
2894c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED);
2895c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->setMessage("format", mOutputFormat);
2896c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        msg->post();
2897c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    }
2898c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang}
2899c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
2900575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() {
2901575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    if (mActivityNotify == NULL) {
2902575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return;
2903575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2904575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2905e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    bool isErrorOrOutputChanged =
2906e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            (mFlags & (kFlagStickyError
2907575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                    | kFlagOutputBuffersChanged
2908e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    | kFlagOutputFormatChanged));
2909e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2910e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang    if (isErrorOrOutputChanged
2911575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexInput].empty()
2912575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
2913e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        mActivityNotify->setInt32("input-buffers",
2914e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                mAvailPortBuffers[kPortIndexInput].size());
2915e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang
2916e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        if (isErrorOrOutputChanged) {
2917e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            // we want consumer to dequeue as many times as it can
2918e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers", INT32_MAX);
2919e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        } else {
2920e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang            mActivityNotify->setInt32("output-buffers",
2921e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang                    mAvailPortBuffers[kPortIndexOutput].size());
2922e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang        }
2923575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify->post();
2924575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        mActivityNotify.clear();
2925575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
2926575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber}
2927575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
2928a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> &params) {
29291d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar    sp<AMessage> msg = new AMessage(kWhatSetParameters, this);
2930a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    msg->setMessage("params", params);
2931a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2932a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    sp<AMessage> response;
2933a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return PostAndAwaitResponse(msg, &response);
2934a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2935a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2936a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
2937a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    mCodec->signalSetParameters(params);
2938a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2939a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    return OK;
2940a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber}
2941a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber
2942e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData(
29437e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        const sp<MediaCodecBuffer> &buffer) {
2944e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    AString mime;
2945e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    CHECK(mOutputFormat->findString("mime", &mime));
2946e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2947e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
2948e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // Codec specific data should be SPS and PPS in a single buffer,
2949e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // each prefixed by a startcode (0x00 0x00 0x00 0x01).
2950e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // We separate the two and put them into the output format
2951e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // under the keys "csd-0" and "csd-1".
2952e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2953e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        unsigned csdIndex = 0;
2954e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2955e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *data = buffer->data();
2956e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t size = buffer->size();
2957e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2958e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        const uint8_t *nalStart;
2959e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        size_t nalSize;
2960e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
2961e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            sp<ABuffer> csd = new ABuffer(nalSize + 4);
2962e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data(), "\x00\x00\x00\x01", 4);
2963e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            memcpy(csd->data() + 4, nalStart, nalSize);
2964e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2965e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            mOutputFormat->setBuffer(
2966a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes                    AStringPrintf("csd-%u", csdIndex).c_str(), csd);
2967e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2968e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            ++csdIndex;
2969e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2970e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2971e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        if (csdIndex != 2) {
2972e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            return ERROR_MALFORMED;
2973e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        }
2974e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    } else {
2975e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // For everything else we just stash the codec specific data into
2976e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        // the output format as a single piece of csd under "csd-0".
29777e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        sp<ABuffer> csd = new ABuffer(buffer->size());
29787e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        memcpy(csd->data(), buffer->data(), buffer->size());
29797e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        csd->setRange(0, buffer->size());
29807e34bf5af26f8752d4786d3098740cdf51e2438fWonsik Kim        mOutputFormat->setBuffer("csd-0", csd);
2981e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
2982e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
2983e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    return OK;
2984e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber}
2985e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber
29862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() {
29873f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    if (!mIsVideo) {
29883f273d10817ddb2f792ae043de692efcdf1988aeWei Jia        return;
29893f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    }
29902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
29913f273d10817ddb2f792ae043de692efcdf1988aeWei Jia    if (mState == CONFIGURED && !mBatteryStatNotified) {
2992f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        BatteryNotifier::getInstance().noteStartVideo(mUid);
29932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = true;
29942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
2995f2ae3e19080938db8cbf29a963fd744a3964fcc2Wei Jia        BatteryNotifier::getInstance().noteStopVideo(mUid);
29962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        mBatteryStatNotified = false;
29972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
29982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}
29992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang
30005778822d86b0337407514b9372562b86edfa91cdAndreas Huber}  // namespace android
3001