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