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