MediaCodec.cpp revision b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537
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/PersistentSurface.h> 488b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar#include <media/stagefright/SurfaceUtils.h> 4999e69716215cd0665379bc90d708f2ea8689831dRuben Brunk#include <mediautils/BatteryNotifier.h> 502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h> 512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h> 522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h> 53e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 545778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android { 555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic int64_t getId(sp<IResourceManagerClient> client) { 5767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (int64_t) client.get(); 5867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 5967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) { 6147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu return (err == NO_MEMORY); 6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2; 654b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wustatic const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s 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(); 774b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu if (err == WOULD_BLOCK) { 784b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu ALOGD("Wait for the client to release codec."); 794b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu usleep(kMaxReclaimWaitTimeInUs); 804b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu ALOGD("Try to reclaim again."); 814b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu err = codec->reclaim(true /* force */); 824b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu } 8367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 8467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerClient failed to release codec with err %d", err); 8567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 8667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (err == OK); 8767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 8867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 898f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu virtual String8 getName() { 908f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu String8 ret; 918f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu sp<MediaCodec> codec = mMediaCodec.promote(); 928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu if (codec == NULL) { 938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu // codec is already gone. 948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu return ret; 958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 968f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu 978f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu AString name; 988f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu if (codec->getName(&name) == OK) { 998f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu ret.setTo(name.c_str()); 1008f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 1018f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu return ret; 1028f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 10367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected: 10567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu virtual ~ResourceManagerClient() {} 10667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate: 10867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu wp<MediaCodec> mMediaCodec; 10967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 11067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient); 11167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}; 11267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 11368845c14ebf2c7282800b1abffde38d8e9a57aabRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid) 11468845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu : mPid(pid) { 11568845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu if (mPid == MediaCodec::kNoPid) { 11668845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mPid = IPCThreadState::self()->getCallingPid(); 11768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu } 11867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 11967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 12067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() { 12167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService != NULL) { 12267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu IInterface::asBinder(mService)->unlinkToDeath(this); 12367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 12467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 12567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 12667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() { 12767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IServiceManager> sm = defaultServiceManager(); 12867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IBinder> binder = sm->getService(String16("media.resource_manager")); 12967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService = interface_cast<IResourceManagerService>(binder); 13067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 13167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("Failed to get ResourceManagerService"); 13267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 13367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 134e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu IInterface::asBinder(mService)->linkToDeath(this); 13567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 13667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 13767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) { 13867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerService died."); 13967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 14067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService.clear(); 14167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 14267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 14367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource( 14467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int64_t clientId, 14567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const sp<IResourceManagerClient> client, 14667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const Vector<MediaResource> &resources) { 14767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 14867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 14967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 15067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 15137c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu mService->addResource(mPid, clientId, client, resources); 15267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 15367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 15467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) { 15567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 15667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 15767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 15867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 15937c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu mService->removeResource(mPid, clientId); 16067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 16167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 16267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource( 16337c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu const Vector<MediaResource> &resources) { 16467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 16567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 16667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return false; 16767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 16837c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu return mService->reclaimResource(mPid, resources); 16967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 17067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 1715778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 1725778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType( 1736fc17d1a7c5d2fb117491b2e9f66c6236b526508Lajos Molnar const sp<ALooper> &looper, const AString &mime, bool encoder, status_t *err, pid_t pid) { 17468845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu sp<MediaCodec> codec = new MediaCodec(looper, pid); 1755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 176251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(mime, true /* nameIsType */, encoder); 177251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 178251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 179251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 180251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1835778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 1845778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName( 1856fc17d1a7c5d2fb117491b2e9f66c6236b526508Lajos Molnar const sp<ALooper> &looper, const AString &name, status_t *err, pid_t pid) { 18668845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu sp<MediaCodec> codec = new MediaCodec(looper, pid); 1875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 188251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */); 189251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 190251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 191251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 192251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 195d291c222357303b9611cab89d0c3b047584ef377Chong Zhang// static 1965b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarstatus_t MediaCodec::QueryCapabilities( 1975b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar const AString &name, const AString &mime, bool isEncoder, 1985b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar sp<MediaCodecInfo::Capabilities> *caps /* nonnull */) { 1995b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // TRICKY: this method is used by MediaCodecList/Info during its 2005b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // initialization. As such, we cannot create a MediaCodec instance 2015b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // because that requires an initialized MediaCodecList. 2025b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 2035b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar sp<CodecBase> codec = GetCodecBase(name); 2045b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (codec == NULL) { 2055b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return NAME_NOT_FOUND; 2065b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 2075b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 2085b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return codec->queryCapabilities(name, mime, isEncoder, caps); 2095b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar} 2105b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 2115b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar// static 212d291c222357303b9611cab89d0c3b047584ef377Chong Zhangsp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() { 213d291c222357303b9611cab89d0c3b047584ef377Chong Zhang OMXClient client; 214d291c222357303b9611cab89d0c3b047584ef377Chong Zhang CHECK_EQ(client.connect(), (status_t)OK); 215d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<IOMX> omx = client.interface(); 216d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 21779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang const sp<IMediaCodecList> mediaCodecList = MediaCodecList::getInstance(); 21879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (mediaCodecList == NULL) { 21979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGE("Failed to obtain MediaCodecList!"); 22079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return NULL; // if called from Java should raise IOException 22179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 22279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 22379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang AString tmp; 22479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang sp<AMessage> globalSettings = mediaCodecList->getGlobalSettings(); 22579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (globalSettings == NULL || !globalSettings->findString( 22679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang kMaxEncoderInputBuffers, &tmp)) { 22779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGE("Failed to get encoder input buffer count!"); 22879608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return NULL; 22979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 23079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 23179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang int32_t bufferCount = strtol(tmp.c_str(), NULL, 10); 23279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (bufferCount <= 0 23379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang || bufferCount > BufferQueue::MAX_MAX_ACQUIRED_BUFFERS) { 23479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGE("Encoder input buffer count is invalid!"); 23579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return NULL; 23679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 23779608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 238d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<IGraphicBufferProducer> bufferProducer; 239d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<IGraphicBufferConsumer> bufferConsumer; 240d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 241d291c222357303b9611cab89d0c3b047584ef377Chong Zhang status_t err = omx->createPersistentInputSurface( 242d291c222357303b9611cab89d0c3b047584ef377Chong Zhang &bufferProducer, &bufferConsumer); 243d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 244d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (err != OK) { 245d291c222357303b9611cab89d0c3b047584ef377Chong Zhang ALOGE("Failed to create persistent input surface."); 246d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return NULL; 247d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 248d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 24979608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang err = bufferConsumer->setMaxAcquiredBufferCount(bufferCount); 25079608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 25179608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang if (err != NO_ERROR) { 25279608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang ALOGE("Unable to set BQ max acquired buffer count to %u: %d", 25379608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang bufferCount, err); 25479608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang return NULL; 25579608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang } 25679608158c2254fe1357959157f2d0c1560a8a6c6Chong Zhang 257d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return new PersistentSurface(bufferProducer, bufferConsumer); 258d291c222357303b9611cab89d0c3b047584ef377Chong Zhang} 259d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 26068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua WuMediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid) 2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber : mState(UNINITIALIZED), 26247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu mReleasedByResourceManager(false), 2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper(looper), 26492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar mCodec(NULL), 2657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID(0), 2665778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags(0), 267251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError(OK), 2685778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer(NULL), 269ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mResourceManagerClient(new ResourceManagerClient(this)), 27068845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu mResourceManagerService(new ResourceManagerServiceProxy(pid)), 2712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified(false), 2722606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mIsVideo(false), 27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoWidth(0), 27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoHeight(0), 275505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang mRotationDegrees(0), 2765778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputTimeoutGeneration(0), 2775778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID(0), 2785778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputTimeoutGeneration(0), 2796507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mDequeueOutputReplyID(0), 2803d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHaveInputSurface(false), 2813d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers(false) { 2825778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 2835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2845778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() { 2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, UNINITIALIZED); 28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 2875778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 2885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 2905778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse( 2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &msg, sp<AMessage> *response) { 2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = msg->postAndAwaitResponse(response); 2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2945778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2985778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!(*response)->findInt32("err", &err)) { 2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = OK; 3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3053f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) { 30647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu int32_t finalErr = err; 30747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu if (mReleasedByResourceManager) { 30847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu // override the err code if MediaCodec has been released by ResourceManager. 30947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu finalErr = DEAD_OBJECT; 31047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu } 31147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 312c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 31347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu response->setInt32("err", finalErr); 314c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 315c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 316c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 3175b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar//static 3185b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnarsp<CodecBase> MediaCodec::GetCodecBase(const AString &name, bool nameIsType) { 3195b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar // at this time only ACodec specifies a mime type. 3205b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (nameIsType || name.startsWithIgnoreCase("omx.")) { 3215b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return new ACodec; 3225b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } else if (name.startsWithIgnoreCase("android.filter.")) { 3235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return new MediaFilter; 3245b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } else { 3255b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar return NULL; 3265b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar } 3275b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar} 3285b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar 329dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) { 33067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->init(); 33167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 332671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // save init parameters for reset 333671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitName = name; 334671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitNameIsType = nameIsType; 335671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitIsEncoder = encoder; 336671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Current video decoders do not return from OMX_FillThisBuffer 3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber // quickly, violating the OpenMAX specs, until that is remedied 3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber // we need to invest in an extra looper to free the main event 3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber // queue. 341744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 3425b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar mCodec = GetCodecBase(name, nameIsType); 3435b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar if (mCodec == NULL) { 344744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return NAME_NOT_FOUND; 345744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 346744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 34767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu bool secureCodec = false; 348dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) { 34967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 3506f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } else { 3516f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen AString tmp = name; 3526f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (tmp.endsWith(".secure")) { 35367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu secureCodec = true; 3546f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen tmp.erase(tmp.size() - 7, 7); 3556f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 35660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); 35748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung if (mcl == NULL) { 35848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung mCodec = NULL; // remove the codec. 35948a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung return NO_INIT; // if called from Java should raise IOException 36048a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung } 3616f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); 3626f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (codecIdx >= 0) { 36360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); 36460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<AString> mimes; 36560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar info->getSupportedMimes(&mimes); 36660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t i = 0; i < mimes.size(); i++) { 36760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (mimes[i].startsWith("video/")) { 36867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 36960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar break; 3706f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 3716f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 3726f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 37567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 37667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // video codec needs dedicated looper 3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mCodecLooper == NULL) { 3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper = new ALooper; 3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->setName("CodecLooper"); 3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 3815778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3835778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->registerHandler(mCodec); 3845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 3855778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(mCodec); 3865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3885778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(this); 3895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this)); 3915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3921d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatInit, this); 3935778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setString("name", name); 3945778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("nameIsType", nameIsType); 3955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3965778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 3975778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("encoder", encoder); 3985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 40167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 402ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::Type type = 403ea15fd29af81490311af9e12949b43524c39400eRonghua Wu secureCodec ? MediaResource::kSecureCodec : MediaResource::kNonSecureCodec; 404ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::SubType subtype = 405ea15fd29af81490311af9e12949b43524c39400eRonghua Wu mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec; 406ea15fd29af81490311af9e12949b43524c39400eRonghua Wu resources.push_back(MediaResource(type, subtype, 1)); 40767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 40867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 40967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 41037c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu if (!mResourceManagerService->reclaimResource(resources)) { 41167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 41267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 41367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 41467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 41567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 41667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 41767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 41867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 41967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 42067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 42167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 424c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) { 4251d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetCallback, this); 426c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("callback", callback); 427c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 428c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response; 429c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang return PostAndAwaitResponse(msg, &response); 430c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 431c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 43290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarstatus_t MediaCodec::setOnFrameRenderedNotification(const sp<AMessage> ¬ify) { 43390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetNotification, this); 43490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar msg->setMessage("on-frame-rendered", notify); 43590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar return msg->post(); 43690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar} 43790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 4385778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure( 4395778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &format, 440f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar const sp<Surface> &surface, 4411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const sp<ICrypto> &crypto, 4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags) { 4431d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigure, this); 4445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 44567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 44667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("width", &mVideoWidth); 44767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("height", &mVideoHeight); 448505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang if (!format->findInt32("rotation-degrees", &mRotationDegrees)) { 449505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang mRotationDegrees = 0; 450505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang } 4512034457336d28124e0f9f3c625978052ae03fceaWei Jia 4522034457336d28124e0f9f3c625978052ae03fceaWei Jia // Prevent possible integer overflow in downstream code. 4532034457336d28124e0f9f3c625978052ae03fceaWei Jia if (mInitIsEncoder 4542034457336d28124e0f9f3c625978052ae03fceaWei Jia && (uint64_t)mVideoWidth * mVideoHeight > (uint64_t)INT32_MAX / 4) { 4552034457336d28124e0f9f3c625978052ae03fceaWei Jia ALOGE("buffer size is too big, width=%d, height=%d", mVideoWidth, mVideoHeight); 4562034457336d28124e0f9f3c625978052ae03fceaWei Jia return BAD_VALUE; 4572034457336d28124e0f9f3c625978052ae03fceaWei Jia } 45867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 45967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 4605778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setMessage("format", format); 4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 462f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar msg->setObject("surface", surface); 4631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 4641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (crypto != NULL) { 4651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber msg->setPointer("crypto", crypto.get()); 4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 46867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // save msg for reset 46967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mConfigureMsg = msg; 470f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 47167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 47267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 473ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::Type type = (mFlags & kFlagIsSecure) ? 474ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::kSecureCodec : MediaResource::kNonSecureCodec; 475ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::SubType subtype = 476ea15fd29af81490311af9e12949b43524c39400eRonghua Wu mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec; 477ea15fd29af81490311af9e12949b43524c39400eRonghua Wu resources.push_back(MediaResource(type, subtype, 1)); 47867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 47967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 480ea15fd29af81490311af9e12949b43524c39400eRonghua Wu resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1)); 48167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 48267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 48367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 48437c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu if (!mResourceManagerService->reclaimResource(resources)) { 48567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 48667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 48767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 488f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 48967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 49067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 49167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK && err != INVALID_OPERATION) { 49267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // MediaCodec now set state to UNINITIALIZED upon any fatal error. 49367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // To maintain backward-compatibility, do a reset() to put codec 49467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // back into INITIALIZED state. 49567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // But don't reset if the err is INVALID_OPERATION, which means 49667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the configure failure is due to wrong state. 49767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 49867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("configure failed with err 0x%08x, resetting...", err); 49967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu reset(); 50067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 50167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 50267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 50367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 504f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang } 505f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang return err; 5065778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5088f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhangstatus_t MediaCodec::setInputSurface( 509d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<PersistentSurface> &surface) { 5108f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang sp<AMessage> msg = new AMessage(kWhatSetInputSurface, this); 511d291c222357303b9611cab89d0c3b047584ef377Chong Zhang msg->setObject("input-surface", surface.get()); 512d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 513d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<AMessage> response; 514d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return PostAndAwaitResponse(msg, &response); 515d291c222357303b9611cab89d0c3b047584ef377Chong Zhang} 516d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 5171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::setSurface(const sp<Surface> &surface) { 5181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> msg = new AMessage(kWhatSetSurface, this); 5191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar msg->setObject("surface", surface); 5201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 5211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> response; 5221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return PostAndAwaitResponse(msg, &response); 5231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 5241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 5257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface( 5267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 5271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this); 5287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 5297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 5307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = PostAndAwaitResponse(msg, &response); 5317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (err == NO_ERROR) { 5327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // unwrap the sp<IGraphicBufferProducer> 5337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 5347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden bool found = response->findObject("input-surface", &obj); 5357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(found); 5367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<BufferProducerWrapper> wrapper( 5377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden static_cast<BufferProducerWrapper*>(obj.get())); 5387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden *bufferProducer = wrapper->getBufferProducer(); 5397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 5407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGW("createInputSurface failed, err=%d", err); 5417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 5427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return err; 5437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 5447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 54567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() { 54667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mIsVideo) { 54767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return 0; 54867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 54967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu uint64_t size = 0; 55167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]); 55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (size_t i = 0; i < portNum; ++i) { 55367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // TODO: this is just an estimation, we should get the real buffer size from ACodec. 55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2; 55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 55667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return size; 55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 559ea15fd29af81490311af9e12949b43524c39400eRonghua Wuvoid MediaCodec::addResource( 560ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::Type type, MediaResource::SubType subtype, uint64_t value) { 56167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 562c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(type, subtype, value)); 56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->addResource( 56437c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu getId(mResourceManagerClient), mResourceManagerClient, resources); 56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 56667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 5675778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() { 5681d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, this); 5695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 57067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 57167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 572ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::Type type = (mFlags & kFlagIsSecure) ? 573ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::kSecureCodec : MediaResource::kNonSecureCodec; 574ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::SubType subtype = 575ea15fd29af81490311af9e12949b43524c39400eRonghua Wu mIsVideo ? MediaResource::kVideoCodec : MediaResource::kAudioCodec; 576ea15fd29af81490311af9e12949b43524c39400eRonghua Wu resources.push_back(MediaResource(type, subtype, 1)); 57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 57867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 579ea15fd29af81490311af9e12949b43524c39400eRonghua Wu resources.push_back(MediaResource(MediaResource::kGraphicMemory, 1)); 58067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 58167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 58337c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu if (!mResourceManagerService->reclaimResource(resources)) { 58467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 58567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 58667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Recover codec from previous error before retry start. 58767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = reset(); 58867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 58967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to reset codec"); 59067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 59167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 59367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(mConfigureMsg, &response); 59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to configure codec"); 59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 59767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 60067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 60167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 60267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 6075778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() { 6101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, this); 6115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6164b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wubool MediaCodec::hasPendingBuffer(int portIndex) { 6174b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu const Vector<BufferInfo> &buffers = mPortBuffers[portIndex]; 6184b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu for (size_t i = 0; i < buffers.size(); ++i) { 6194b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu const BufferInfo &info = buffers.itemAt(i); 6204b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu if (info.mOwnedByClient) { 6214b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu return true; 6224b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu } 6234b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu } 6244b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu return false; 6254b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu} 6264b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu 6274b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wubool MediaCodec::hasPendingBuffer() { 6284b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu return hasPendingBuffer(kPortIndexInput) || hasPendingBuffer(kPortIndexOutput); 6294b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu} 6304b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu 6314b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wustatus_t MediaCodec::reclaim(bool force) { 63258828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu ALOGD("MediaCodec::reclaim(%p) %s", this, mInitName.c_str()); 63347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu sp<AMessage> msg = new AMessage(kWhatRelease, this); 63447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu msg->setInt32("reclaimed", 1); 6354b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu msg->setInt32("force", force ? 1 : 0); 63647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 63747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu sp<AMessage> response; 6380abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu status_t ret = PostAndAwaitResponse(msg, &response); 6390abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu if (ret == -ENOENT) { 6400abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu ALOGD("MediaCodec looper is gone, skip reclaim"); 6410abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu ret = OK; 6420abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu } 6430abb2aa4859ced9165c77324cb83d1cd94f5f20cRonghua Wu return ret; 64447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu} 64547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 646c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() { 6471d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRelease, this); 648c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 649c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response; 650c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return PostAndAwaitResponse(msg, &response); 651c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 652c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 653671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() { 654671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar /* When external-facing MediaCodec object is created, 655671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar it is already initialized. Thus, reset is essentially 656671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar release() followed by init(), plus clearing the state */ 657671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 658671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar status_t err = release(); 659671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 660671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // unregister handlers 661671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodec != NULL) { 662671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodecLooper != NULL) { 663671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodecLooper->unregisterHandler(mCodec->id()); 664671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } else { 665671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(mCodec->id()); 666671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 667671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodec = NULL; 668671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 669671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(id()); 670671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 671671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mFlags = 0; // clear all flags 672251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 673671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 674671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // reset state not reset by setState(UNINITIALIZED) 675671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mReplyID = 0; 676671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputReplyID = 0; 677671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputReplyID = 0; 678671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputTimeoutGeneration = 0; 679671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputTimeoutGeneration = 0; 680671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mHaveInputSurface = false; 681671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 682671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (err == OK) { 683dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung err = init(mInitName, mInitNameIsType, mInitIsEncoder); 684671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 685671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar return err; 686671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar} 687671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 6885778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer( 6895778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index, 6905778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset, 6915778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size, 6925778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t presentationTimeUs, 6935b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 6945b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 6955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 6965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 6975b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 6985b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 6991d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 7005778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7015778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("offset", offset); 7025778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("size", size); 7035778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 7045778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 7055b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7075778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer( 7124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t index, 7134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t offset, 7144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples, 7154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples, 7164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t key[16], 7174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t iv[16], 7184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode, 71918cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker const CryptoPlugin::Pattern &pattern, 7204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int64_t presentationTimeUs, 7215b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 7225b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 7235b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 7245b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 7255b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 7265b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 7284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("index", index); 7294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("offset", offset); 7304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("subSamples", (void *)subSamples); 7314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("numSubSamples", numSubSamples); 7324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("key", (void *)key); 7334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("iv", (void *)iv); 7344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("mode", mode); 73518cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker msg->setInt32("encryptBlocks", pattern.mEncryptBlocks); 73618cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker msg->setInt32("skipBlocks", pattern.mSkipBlocks); 7374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 7384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("flags", flags); 7395b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 7404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber sp<AMessage> response; 7425b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber status_t err = PostAndAwaitResponse(msg, &response); 7435b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7445b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber return err; 7454b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber} 7464b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7475778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 7481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this); 7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7625778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer( 7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *index, 7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *offset, 7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *size, 7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t *presentationTimeUs, 7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t *flags, 7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs) { 7691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this); 7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("offset", offset)); 7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("size", size)); 7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt64("timeUs", presentationTimeUs)); 7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt32("flags", (int32_t *)flags)); 7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7875778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 7881d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("render", true); 7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 796fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) { 7971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 798fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setSize("index", index); 799fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt32("render", true); 800fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt64("timestampNs", timestampNs); 801fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 802fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar sp<AMessage> response; 803fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar return PostAndAwaitResponse(msg, &response); 804fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar} 805fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 8065778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) { 8071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 8095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8105778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() { 8151d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this); 8167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 8177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 8187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return PostAndAwaitResponse(msg, &response); 8197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 8207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 8215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 8221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this); 8235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8245778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8255778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 8265778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 8275778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 8285778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 8295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8305778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findMessage("format", format)); 8315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 835e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const { 8361d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this); 837e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 838e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> response; 839e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar status_t err; 840e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 841e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return err; 842e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 843e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 844e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(response->findMessage("format", format)); 845e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 846e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return OK; 847e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar} 848e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 849717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const { 8501d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetName, this); 851717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 852717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response; 853717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo status_t err; 854717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 855717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return err; 856717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 857717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 858717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(response->findString("name", name)); 859717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 860717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return OK; 861717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo} 862717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 863e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const { 864e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 865e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("portIndex", kPortIndexInput); 866e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setPointer("buffers", buffers); 867e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("widevine", true); 868e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 869e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> response; 870e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar return PostAndAwaitResponse(msg, &response); 871e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar} 872e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 8735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 8741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8755778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexInput); 8765778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8785778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8805778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 8831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8845778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexOutput); 8855778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8875778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8885778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8895778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) { 8927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 8937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, buffer, &format); 8947bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) { 8977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> buffer; 8987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, &buffer, format); 8997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) { 9027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 9037bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexInput, index, buffer, &format); 9047bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9057bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9060e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const { 9070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar return mState == STARTED || mState == FLUSHED; 9080e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar} 9090e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar 9107bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat( 9117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar size_t portIndex, size_t index, 9127bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> *buffer, sp<AMessage> *format) { 9137bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // use mutex instead of a context switch 91447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu if (mReleasedByResourceManager) { 915b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage ALOGE("getBufferAndFormat - resource already released"); 91647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu return DEAD_OBJECT; 91747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu } 91847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 919b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage if (buffer == NULL) { 920b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage ALOGE("getBufferAndFormat - null ABuffer"); 921b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage return INVALID_OPERATION; 922b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage } 923b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage 924b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage if (format == NULL) { 925b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage ALOGE("getBufferAndFormat - null AMessage"); 926b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage return INVALID_OPERATION; 927b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage } 928b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage 9297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar buffer->clear(); 9307bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar format->clear(); 931b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage 9320e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 933b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage ALOGE("getBufferAndFormat - not executing"); 9347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return INVALID_OPERATION; 9357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 9367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we do not want mPortBuffers to change during this section 9387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we also don't want mOwnedByClient to change during this 9397bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 940b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage 9417bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 942b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage if (index >= buffers->size()) { 943b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage ALOGE("getBufferAndFormat - trying to get buffer with " 9440362655ca9494052f348f83dabecf9ea27003976Aaron Vaage "bad index (index=%zu buffer_size=%zu)", index, buffers->size()); 945b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage return INVALID_OPERATION; 9467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 947b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage 948b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage const BufferInfo &info = buffers->itemAt(index); 949b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage if (!info.mOwnedByClient) { 950b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage ALOGE("getBufferAndFormat - invalid operation " 9510362655ca9494052f348f83dabecf9ea27003976Aaron Vaage "(the index %zu is not owned by client)", index); 952b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage return INVALID_OPERATION; 953b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage } 954b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage 955b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage // by the time buffers array is initialized, crypto is set 956b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage *buffer = (portIndex == kPortIndexInput && mCrypto != NULL) ? 957b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage info.mEncryptedData : 958b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage info.mData; 959b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage 960b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage *format = info.mFormat; 961b22909302f02bb33ee6264f9a64cd0a4f3790f48Aaron Vaage 9627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return OK; 9637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9655778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() { 9661d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFlush, this); 9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 972496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() { 9731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatRequestIDRFrame, this))->post(); 974496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 975496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber return OK; 976496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 977496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 978575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 9791d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this); 980575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->setMessage("notify", notify); 981575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->post(); 982575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 983575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber//////////////////////////////////////////////////////////////////////////////// 9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9865778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() { 9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueInputPending) { 988c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION); 9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueOutputPending) { 996c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION); 9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10043f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 10050e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueInputPending))) { 1007c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 1009251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1010251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1011251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return true; 10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10283f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 10290e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 103147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu PostReplyWithError(replyID, INVALID_OPERATION); 1032251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 103347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu PostReplyWithError(replyID, getStickyError()); 10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputBuffersChanged) { 103547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED); 10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputFormatChanged) { 103847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu PostReplyWithError(replyID, INFO_FORMAT_CHANGED); 10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 104147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu sp<AMessage> response = new AMessage; 10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexOutput); 10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<ABuffer> &buffer = 10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[kPortIndexOutput].itemAt(index).mData; 10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("offset", buffer->offset()); 10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("size", buffer->size()); 10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt64("timeUs", timeUs); 10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags = 0; 10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_SYNCFRAME; 10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_CODECCONFIG; 10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_EOS) { 10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_EOS; 10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("flags", flags); 107647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu response->postReply(replyID); 10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10825778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (msg->what()) { 10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatCodecNotify: 10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t what; 10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("what", &what)); 10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (what) { 109092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatError: 10915778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1092251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung int32_t err, actionCode; 1093251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("err", &err)); 1094251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("actionCode", &actionCode)); 10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10969e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen ALOGE("Codec reported err %#x, actionCode %d, while in state %d", 10979e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen err, actionCode, mState); 1098251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err == DEAD_OBJECT) { 1099aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags |= kFlagSawMediaServerDie; 110052dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 1101aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1102aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 11035530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia bool sendErrorResponse = true; 11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (mState) { 11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber case INITIALIZING: 11075778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(UNINITIALIZED); 11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber case CONFIGURING: 11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1114c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1115c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : INITIALIZED); 11165778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTING: 11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1121c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1122c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : CONFIGURED); 11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STOPPING: 1127c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case RELEASING: 11285778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Ignore the error, assuming we'll still get 11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber // the shutdown complete notification. 11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11325530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 113303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 1134aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 113503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // MediaServer died, there definitely won't 113603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // be a shutdown complete notification after 113703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // all. 113803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 113903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // note that we're directly going from 114003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // STOPPING->UNINITIALIZED, instead of the 114103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // usual STOPPING->INITIALIZED state. 114203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber setState(UNINITIALIZED); 11436e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (mState == RELEASING) { 11446e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 11456e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 114603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber (new AMessage)->postReply(mReplyID); 114703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber } 11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber case FLUSHING: 11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11539e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen if (actionCode == ACTION_CODE_FATAL) { 11549e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState(UNINITIALIZED); 11559e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } else { 11569e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState( 11579e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen (mFlags & kFlagIsAsync) ? FLUSHED : STARTED); 11589e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } 11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11620e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar case FLUSHED: 11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTED: 11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11655530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1167251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1168575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 1171c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1172c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1173251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1174251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1175251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1176251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1177251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1178251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1179251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1180251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1181251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1182251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1183251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1184c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11905530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1192251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1193575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1194c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1195251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung // actionCode in an uninitialized state is always fatal. 1196251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (mState == UNINITIALIZED) { 1197251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung actionCode = ACTION_CODE_FATAL; 1198251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1199c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1200251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1201251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1202251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1203251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1204251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1205251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1206251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1207251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1208251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1209251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1210251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1211c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12165530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (sendErrorResponse) { 1217251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(mReplyID, err); 12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 122292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentAllocated: 12235778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, INITIALIZING); 12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZED); 122652dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags |= kFlagIsComponentAllocated; 12275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1228717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->findString("componentName", &mComponentName)); 12295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1230717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.startsWith("OMX.google.")) { 12313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 12325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 12333a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags &= ~kFlagUsesSoftwareRenderer; 12345778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1236ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::Type resourceType; 1237717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.endsWith(".secure")) { 12381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags |= kFlagIsSecure; 1239ea15fd29af81490311af9e12949b43524c39400eRonghua Wu resourceType = MediaResource::kSecureCodec; 12401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 12411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags &= ~kFlagIsSecure; 1242ea15fd29af81490311af9e12949b43524c39400eRonghua Wu resourceType = MediaResource::kNonSecureCodec; 12431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1244c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu 124558828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu if (mIsVideo) { 124658828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu // audio codec is currently ignored. 1247ea15fd29af81490311af9e12949b43524c39400eRonghua Wu addResource(resourceType, MediaResource::kVideoCodec, 1); 124858828196edf2fc4debbd7913198a8149f039b4a9Ronghua Wu } 12491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 125492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentConfigured: 12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1256c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung if (mState == UNINITIALIZED || mState == INITIALIZED) { 1257c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung // In case a kWhatError message came in and replied with error, 1258c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung // we log a warning and ignore. 1259c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung ALOGW("configure interrupted by error, current state %d", mState); 1260c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung break; 1261c6044a135324979e62cc59db9dbde8b11c4bb74bAndy Hung } 12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, CONFIGURING); 12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden // reset input surface flag 12656507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = false; 12666507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 1267e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("input-format", &mInputFormat)); 1268e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("output-format", &mOutputFormat)); 1269b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("[%s] configured as input format: %s, output format: %s", 1270b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str(), 1271b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mInputFormat->debugString(4).c_str(), 1272b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mOutputFormat->debugString(4).c_str()); 12733a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar int32_t usingSwRenderer; 12743a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer) 12753a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar && usingSwRenderer) { 12763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 12773a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 12782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang setState(CONFIGURED); 12795778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 12805778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12815778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 128392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatInputSurfaceCreated: 12847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 128592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to initiateCreateInputSurface() 12867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = NO_ERROR; 12871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> response = new AMessage; 12887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (!msg->findInt32("err", &err)) { 12897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 12907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden msg->findObject("input-surface", &obj); 1291b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar CHECK(msg->findMessage("input-format", &mInputFormat)); 1292b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar CHECK(msg->findMessage("output-format", &mOutputFormat)); 1293b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("[%s] input surface created as input format: %s, output format: %s", 1294b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str(), 1295b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mInputFormat->debugString(4).c_str(), 1296b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mOutputFormat->debugString(4).c_str()); 12977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(obj != NULL); 12987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setObject("input-surface", obj); 12996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = true; 13007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 13017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 13027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 13037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 13047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 13057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 13067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 1307d291c222357303b9611cab89d0c3b047584ef377Chong Zhang case CodecBase::kWhatInputSurfaceAccepted: 1308d291c222357303b9611cab89d0c3b047584ef377Chong Zhang { 13098f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang // response to initiateSetInputSurface() 1310d291c222357303b9611cab89d0c3b047584ef377Chong Zhang status_t err = NO_ERROR; 1311d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<AMessage> response = new AMessage(); 1312d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (!msg->findInt32("err", &err)) { 1313d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mHaveInputSurface = true; 1314d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 1315d291c222357303b9611cab89d0c3b047584ef377Chong Zhang response->setInt32("err", err); 1316d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 1317d291c222357303b9611cab89d0c3b047584ef377Chong Zhang response->postReply(mReplyID); 1318d291c222357303b9611cab89d0c3b047584ef377Chong Zhang break; 1319d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 1320d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 132192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatSignaledInputEOS: 13227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 132392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to signalEndOfInputStream() 13241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> response = new AMessage; 13257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err; 13267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (msg->findInt32("err", &err)) { 13277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 13287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 13297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 13307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 13317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 13327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 13337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 133492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatBuffersAllocated: 13355778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("%s buffers allocated", 13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber portIndex == kPortIndexInput ? "input" : "output"); 13425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13435778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput 13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber || portIndex == kPortIndexOutput); 13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[portIndex].clear(); 13475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1350eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber sp<RefBase> obj; 1351eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber CHECK(msg->findObject("portDesc", &obj)); 1352eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 135392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar sp<CodecBase::PortDescription> portDesc = 135492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar static_cast<CodecBase::PortDescription *>(obj.get()); 13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1356eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber size_t numBuffers = portDesc->countBuffers(); 13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1358c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker size_t totalSize = 0; 1359c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker for (size_t i = 0; i < numBuffers; ++i) { 1360c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (portIndex == kPortIndexInput && mCrypto != NULL) { 1361c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker totalSize += portDesc->bufferAt(i)->capacity(); 1362c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1363c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1364c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1365c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (totalSize) { 1366c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker mDealer = new MemoryDealer(totalSize, "MediaCodec"); 1367c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1368c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1369eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber for (size_t i = 0; i < numBuffers; ++i) { 13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo info; 1371eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mBufferID = portDesc->bufferIDAt(i); 13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber info.mOwnedByClient = false; 1373eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mData = portDesc->bufferAt(i); 1374a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar info.mNativeHandle = portDesc->handleAt(i); 137586b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu info.mMemRef = portDesc->memRefAt(i); 13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (portIndex == kPortIndexInput && mCrypto != NULL) { 1378c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sp<IMemory> mem = mDealer->allocate(info.mData->capacity()); 1379ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info.mEncryptedData = 1380c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker new ABuffer(mem->pointer(), info.mData->capacity()); 1381c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info.mSharedEncryptedBuffer = mem; 1382ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 1383ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffers->push_back(info); 13855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexOutput) { 13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState == STARTING) { 13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We're always allocating output buffers after 13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber // allocating input buffers, so this is a good 13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber // indication that now all buffers are allocated. 139267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 1393c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu addResource( 1394ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::kGraphicMemory, 1395ea15fd29af81490311af9e12949b43524c39400eRonghua Wu MediaResource::kUnspecifiedSubType, 1396c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu getGraphicBufferSize()); 139767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTED); 13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagOutputBuffersChanged; 1402575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 140892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatOutputFormatChanged: 14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1410b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar CHECK(msg->findMessage("format", &mOutputFormat)); 1411b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar 1412b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGV("[%s] output format changed to: %s", 1413b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str(), mOutputFormat->debugString(4).c_str()); 1414b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 1415475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mSoftRenderer == NULL && 1416f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar mSurface != NULL && 14173a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar (mFlags & kFlagUsesSoftwareRenderer)) { 14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString mime; 1419b0a4b9e917bd26bf366fb20c48315f51285c18f9Lajos Molnar CHECK(mOutputFormat->findString("mime", &mime)); 14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1421b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // TODO: propagate color aspects to software renderer to allow better 1422b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // color conversion to RGB. For now, just mark dataspace for YUV 1423b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar // rendering. 1424b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int32_t dataSpace; 1425b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar if (mOutputFormat->findInt32("android._dataspace", &dataSpace)) { 1426b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGD("[%s] setting dataspace on output surface to #%x", 1427b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mComponentName.c_str(), dataSpace); 1428b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar int err = native_window_set_buffers_data_space( 1429b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar mSurface.get(), (android_dataspace)dataSpace); 1430b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar ALOGW_IF(err != 0, "failed to set dataspace on surface (%d)", err); 1431b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar } 1432b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar 1433475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mime.startsWithIgnoreCase("video/")) { 1434505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees); 14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagIsEncoder) { 1439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Before we announce the format change we should 1440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // collect codec specific data and amend the output 1441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format as necessary. 1442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagGatherCodecSpecificData; 1443c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagIsAsync) { 1444c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 1446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagOutputFormatChanged; 1447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber postActivityNotificationIfPossible(); 1448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 14492514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 14502514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker // Notify mCrypto of video resolution changes 14512514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker if (mCrypto != NULL) { 14528140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar int32_t left, top, right, bottom, width, height; 14538140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { 14548140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(right - left + 1, bottom - top + 1); 14558140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } else if (mOutputFormat->findInt32("width", &width) 14568140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar && mOutputFormat->findInt32("height", &height)) { 14578140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(width, height); 14588140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } 14592514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 14602514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 146490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar case CodecBase::kWhatOutputFramesRendered: 146590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar { 146690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // ignore these in all states except running, and check that we have a 146790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // notification set 146890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (mState == STARTED && mOnFrameRenderedNotification != NULL) { 146990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar sp<AMessage> notify = mOnFrameRenderedNotification->dup(); 147090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar notify->setMessage("data", msg); 147190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar notify->post(); 147290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 147390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar break; 147490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 147590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 147692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFillThisBuffer: 14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexInput, msg); 14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1482c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (!mCSD.empty()) { 14888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 14898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK_GE(index, 0); 14908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 14918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // If codec specific data had been specified as 14928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // part of the format in the call to configure and 14938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // if there's more csd left, we submit it here 14948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // clients only get access to input buffers once 14958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // this data has been exhausted. 14968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 14978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber status_t err = queueCSDInputBuffer(index); 14988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 14998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (err != OK) { 15008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ALOGE("queueCSDInputBuffer failed w/ error %d", 15018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber err); 15028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1503251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1504575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1505575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 15068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber cancelPendingDequeueOperations(); 15078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 15088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 15098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 15108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1511c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 15126e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (!mHaveInputSurface) { 15133d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mState == FLUSHED) { 15143d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = true; 15153d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } else { 15163d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 15173d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 15186e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1519c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueInputPending) { 15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 1525575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1526575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 153192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatDrainThisBuffer: 15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexOutput, msg); 15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1535c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1536c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1537c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15422d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 15432d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", &omxFlags)); 15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("omxFlags", omxFlags); 15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagGatherCodecSpecificData) { 1551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // This is the very first output buffer after a 1552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format change was signalled, it'll either contain 1553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the one piece of codec specific data we can expect 1554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // or there won't be codec specific data. 1555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 1556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber status_t err = 1557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber amendOutputFormatWithCodecSpecificData(buffer); 1558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (err != OK) { 1560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ALOGE("Codec spit out malformed codec " 1561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber "specific data!"); 1562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 1566c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1567c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1568c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagOutputFormatChanged; 1570c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1573c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1574c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputBufferAvailable(); 1575c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueOutputPending) { 15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15785778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 1581575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1582575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1584575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 158892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatEOS: 15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We already notify the client of this by using the 15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber // corresponding flag in "onOutputBufferReady". 15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 159592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatShutdownCompleted: 15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1597c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == STOPPING) { 1598c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(INITIALIZED); 1599c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } else { 1600c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK_EQ(mState, RELEASING); 1601c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(UNINITIALIZED); 16026e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 1603c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 160452dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 160667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 160767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 161292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFlushCompleted: 16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 16145530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (mState != FLUSHING) { 16155530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia ALOGW("received FlushCompleted message in state %d", 16165530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia mState); 16175530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia break; 16185530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia } 16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16200e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mFlags & kFlagIsAsync) { 16210e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(FLUSHED); 16220e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else { 16230e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(STARTED); 16240e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 16250e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } 16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatInit: 16385778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 16393f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != UNINITIALIZED) { 1643c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16455778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 16485778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZING); 16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString name; 16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("name", &name)); 16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t nameIsType; 16545778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t encoder = false; 16550db280176bd3277e3256252d063f3712b1905ba9Andreas Huber CHECK(msg->findInt32("nameIsType", &nameIsType)); 16560db280176bd3277e3256252d063f3712b1905ba9Andreas Huber if (nameIsType) { 16575778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("encoder", &encoder)); 16585778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format = new AMessage; 16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16625778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("mime", name.c_str()); 16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", encoder); 16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("componentName", name.c_str()); 16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateAllocateComponent(format); 16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 167390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar case kWhatSetNotification: 167490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar { 167590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar sp<AMessage> notify; 167690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (msg->findMessage("on-frame-rendered", ¬ify)) { 167790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mOnFrameRenderedNotification = notify; 167890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 167990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar break; 168090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 168190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 1682c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang case kWhatSetCallback: 1683c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang { 16843f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1685c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 1686c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1687c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mState == UNINITIALIZED 1688c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang || mState == INITIALIZING 16890e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar || isExecuting()) { 16900e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // callback can't be set after codec is executing, 1691c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // or before it's initialized (as the callback 1692c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // will be cleared when it goes to INITIALIZED) 1693c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1694c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1695c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1696c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1697c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> callback; 1698c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->findMessage("callback", &callback)); 1699c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1700c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback = callback; 1701c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1702c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 1703c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGI("MediaCodec will operate in async mode"); 1704c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagIsAsync; 1705c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1706c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 1707c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1708c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1709c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 1710c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 1711c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1712c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1713c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 17145778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatConfigure: 17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 17163f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17195778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != INITIALIZED) { 1720c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 17215778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17225778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<RefBase> obj; 1725f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar CHECK(msg->findObject("surface", &obj)); 17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format; 17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("format", &format)); 17295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17308b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar int32_t push; 17318b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) { 17328b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar mFlags |= kFlagPushBlankBuffersOnShutdown; 17338b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar } 17348b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar 17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (obj != NULL) { 17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setObject("native-window", obj); 1737f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar status_t err = handleSetSurface(static_cast<Surface *>(obj.get())); 17387541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 1739c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 17407541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber break; 17411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 17421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 1743f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar handleSetSurface(NULL); 17441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 17451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 17467541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mReplyID = replyID; 17477541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setState(CONFIGURING); 17487541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 17491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber void *crypto; 17501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (!msg->findPointer("crypto", &crypto)) { 17511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber crypto = NULL; 17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto = static_cast<ICrypto *>(crypto); 17551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & CONFIGURE_FLAG_ENCODE) { 17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", true); 1761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagIsEncoder; 17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber extractCSD(format); 17658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateConfigureComponent(format); 17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case kWhatSetSurface: 17711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar { 17721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AReplyToken> replyID; 17731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 17741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 17751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = OK; 17761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<Surface> surface; 17771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 17781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar switch (mState) { 17791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case CONFIGURED: 17801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case STARTED: 17811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case FLUSHED: 17821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar { 17831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<RefBase> obj; 17841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar (void)msg->findObject("surface", &obj); 17851dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<Surface> surface = static_cast<Surface *>(obj.get()); 17861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mSurface == NULL) { 17871dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // do not support setting surface if it was not set 17881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = INVALID_OPERATION; 17891dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else if (obj == NULL) { 17901dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // do not support unsetting surface 17911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = BAD_VALUE; 17921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else { 17931dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = connectToSurface(surface); 1794098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar if (err == ALREADY_EXISTS) { 1795098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar // reconnecting to same surface 17961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = OK; 17971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else { 17981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == OK) { 17991dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mFlags & kFlagUsesSoftwareRenderer) { 18008b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar if (mSoftRenderer != NULL 18018b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar && (mFlags & kFlagPushBlankBuffersOnShutdown)) { 18028b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar pushBlankBuffersToNativeWindow(mSurface.get()); 18038b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar } 18041dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mSoftRenderer = new SoftwareRenderer(surface); 18051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // TODO: check if this was successful 18061dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else { 18071dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = mCodec->setSurface(surface); 18081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 18091dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 18101dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == OK) { 18111dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar (void)disconnectFromSurface(); 18121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mSurface = surface; 18131dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 18141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 18151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 18161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar break; 18171dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 18181dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 18191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar default: 18201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = INVALID_OPERATION; 18211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar break; 18221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 18231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 18241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar PostReplyWithError(replyID, err); 18251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar break; 18261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 18271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 18287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatCreateInputSurface: 18298f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang case kWhatSetInputSurface: 18307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 18313f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 18337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 18347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // Must be configured, but can't have been started yet. 18357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (mState != CONFIGURED) { 1836c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 18387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 18397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 18407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 1841d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (msg->what() == kWhatCreateInputSurface) { 1842d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mCodec->initiateCreateInputSurface(); 1843d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 1844d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<RefBase> obj; 1845d291c222357303b9611cab89d0c3b047584ef377Chong Zhang CHECK(msg->findObject("input-surface", &obj)); 1846d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 18478f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang mCodec->initiateSetInputSurface( 1848d291c222357303b9611cab89d0c3b047584ef377Chong Zhang static_cast<PersistentSurface *>(obj.get())); 1849d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 18507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 18517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStart: 18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18543f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18570e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mState == FLUSHED) { 1858d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang setState(STARTED); 18593d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mHavePendingInputBuffers) { 18603d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 18613d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = false; 18623d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 18630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 18640e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar PostReplyWithError(replyID, OK); 1865d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang break; 18660e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else if (mState != CONFIGURED) { 1867c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTING); 18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateStart(); 18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStop: 1879c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case kWhatRelease: 1880c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 1881aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber State targetState = 1882aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 1883aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 18843f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1885c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 1886c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 188747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu // already stopped/released 188847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu if (mState == UNINITIALIZED && mReleasedByResourceManager) { 188947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu sp<AMessage> response = new AMessage; 189047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu response->setInt32("err", OK); 189147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu response->postReply(replyID); 189247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu break; 189347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu } 189447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 189547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu int32_t reclaimed = 0; 189647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu msg->findInt32("reclaimed", &reclaimed); 189747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu if (reclaimed) { 189847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu mReleasedByResourceManager = true; 18994b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu 19004b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu int32_t force = 0; 19014b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu msg->findInt32("force", &force); 19024b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu if (!force && hasPendingBuffer()) { 19034b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu ALOGW("Can't reclaim codec right now due to pending buffers."); 19044b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu 19054b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu // return WOULD_BLOCK to ask resource manager to retry later. 19064b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu sp<AMessage> response = new AMessage; 19074b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu response->setInt32("err", WOULD_BLOCK); 19084b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu response->postReply(replyID); 19094b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu 19104b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu // notify the async client 19114b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu if (mFlags & kFlagIsAsync) { 19124b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu onError(DEAD_OBJECT, ACTION_CODE_FATAL); 19134b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu } 19144b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu break; 19154b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu } 191647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu } 191747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 191833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 191933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung && mState != INITIALIZED 19200e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar && mState != CONFIGURED && !isExecuting()) { 192133223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 1) Permit release to shut down the component if allocated. 192233223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 192333223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 2) We may be in "UNINITIALIZED" state already and 192452dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan // also shutdown the encoder/decoder without the 192503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // client being aware of this if media server died while 192603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // we were being stopped. The client would assume that 192703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // after stop() returned, it would be safe to call release() 192803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // and it should be in this case, no harm to allow a release() 192903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // if we're already uninitialized. 1930c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response = new AMessage; 193147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu // TODO: we shouldn't throw an exception for stop/release. Change this to wait until 193247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu // the previous stop/release completes and then reply with OK. 19336e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar status_t err = mState == targetState ? OK : INVALID_OPERATION; 19346e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar response->setInt32("err", err); 19356e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (err == OK && targetState == UNINITIALIZED) { 19366e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 19376e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1938c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber response->postReply(replyID); 1939c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 1940c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 1941c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 1942aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 1943aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // It's dead, Jim. Don't expect initiateShutdown to yield 1944aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // any useful results now... 1945aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(UNINITIALIZED); 19466e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (targetState == UNINITIALIZED) { 19476e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 19486e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1949aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (new AMessage)->postReply(replyID); 1950aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber break; 1951aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1952aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1953c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mReplyID = replyID; 1954aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 1955aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1956aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mCodec->initiateShutdown( 1957aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber msg->what() == kWhatStop /* keepComponentAllocated */); 1958c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 195986b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu returnBuffersToCodec(reclaimed); 19608b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar 19618b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) { 19628b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar pushBlankBuffersToNativeWindow(mSurface.get()); 19638b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar } 19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputBuffer: 19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19693f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1972c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1973c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1974c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1975c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1976c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1977c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 19786507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden if (mHaveInputSurface) { 19796507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden ALOGE("dequeueInputBuffer can't be used with input surface"); 1980c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19816507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden break; 19826507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden } 19836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueInputBuffer(replyID, true /* new request */)) { 19855778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1992c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueInputPending; 19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = replyID; 19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 20011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueInputTimedOut, this); 20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueInputTimeoutGeneration); 20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputTimedOut: 20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueInputTimeoutGeneration) { 20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueInputPending); 20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2021c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, -EAGAIN); 20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20285778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatQueueInputBuffer: 20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 20303f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2033251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 2034c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2036251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2037251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2038251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onQueueInputBuffer(msg); 20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2043c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputBuffer: 20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 20493f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 20505778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2052c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 2053c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 2054c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 2055c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 2056c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2057c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 20585778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 20595778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20605778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20625778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 20635778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 20645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20655778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 2066c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 20675778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20705778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueOutputPending; 20715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = replyID; 20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 20745778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 20751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueOutputTimedOut, this); 20765778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 20775778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueOutputTimeoutGeneration); 20785778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 20795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20815778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputTimedOut: 20845778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueOutputTimeoutGeneration) { 20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueOutputPending); 20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2095c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, -EAGAIN); 20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21025778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatReleaseOutputBuffer: 21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 21043f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 2108c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2111251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onReleaseOutputBuffer(msg); 21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2117c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 21185778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 21195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatSignalEndOfInputStream: 21227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 21233f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 21247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 21257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 2126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 2127c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 21287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 2129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 21327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 21337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 21347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 21357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->signalEndOfInputStream(); 21367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 21377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 21387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetBuffers: 21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 21413f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 2143e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // Unfortunately widevine legacy source requires knowing all of the 2144e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // codec input buffers, so we have to provide them even in async mode. 2145e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar int32_t widevine = 0; 2146e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->findInt32("widevine", &widevine); 21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2148e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) { 2149c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2152251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2153251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<sp<ABuffer> > *dstBuffers; 21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber dstBuffers->clear(); 21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < srcBuffers.size(); ++i) { 21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber const BufferInfo &info = srcBuffers.itemAt(i); 21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2168ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber dstBuffers->push_back( 21691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (portIndex == kPortIndexInput && mCrypto != NULL) 2170ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ? info.mEncryptedData : info.mData); 21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(replyID); 21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatFlush: 21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 21793f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2182251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 2183c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2185251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2186251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2187251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 21910e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // TODO: skip flushing if already FLUSHED 21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(FLUSHING); 21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->signalFlush(); 21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2199e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar case kWhatGetInputFormat: 22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetOutputFormat: 22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 2202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> format = 2203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat); 2204e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 22053f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2208e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((mState != CONFIGURED && mState != STARTING && 22090e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != STARTED && mState != FLUSHING && 22100e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != FLUSHED) 2211e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar || format == NULL) { 2212c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 22135778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2214251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2215251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2216251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 22175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22195778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 2220e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar response->setMessage("format", format); 22215778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 22225778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 22235778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2225496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 2226496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 2227496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mCodec->signalRequestIDRFrame(); 2228496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 2229496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 2230496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 2231575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber case kWhatRequestActivityNotification: 2232575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber { 2233575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(mActivityNotify == NULL); 2234575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(msg->findMessage("notify", &mActivityNotify)); 2235575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2236575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 2237575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber break; 2238575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2239575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2240717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo case kWhatGetName: 2241717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo { 22423f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2243717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->senderAwaitsResponse(&replyID)); 2244717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2245717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.empty()) { 2246c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 2247717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2248717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2249717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2250717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response = new AMessage; 2251717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->setString("name", mComponentName.c_str()); 2252717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->postReply(replyID); 2253717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2254717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2255717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2256a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber case kWhatSetParameters: 2257a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber { 22583f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2259a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 2260a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2261a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> params; 2262a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->findMessage("params", ¶ms)); 2263a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2264a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber status_t err = onSetParameters(params); 2265a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2266c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 2267a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber break; 2268a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 2269a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22758ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) { 22768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.clear(); 22778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber size_t i = 0; 22798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber for (;;) { 22808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd; 2281a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) { 22828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 22838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 22844f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang if (csd->size() == 0) { 22854f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang ALOGW("csd-%zu size is 0", i); 22864f59c7e373a7e883f21ba33d44ea7caa86b65b02Hangyu Kuang } 22878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.push_back(csd); 22898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ++i; 22908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 22918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 2292a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("Found %zu pieces of codec specific data.", mCSD.size()); 22938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 22948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 22968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK(!mCSD.empty()); 22978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo *info = 22997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar &mPortBuffers[kPortIndexInput].itemAt(bufferIndex); 23008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 23018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd = *mCSD.begin(); 23028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.erase(mCSD.begin()); 23038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 23048ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber const sp<ABuffer> &codecInputData = 23058ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber (mCrypto != NULL) ? info->mEncryptedData : info->mData; 23068ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 23078ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (csd->size() > codecInputData->capacity()) { 23088ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return -EINVAL; 23098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 23108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 23118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber memcpy(codecInputData->data(), csd->data(), csd->size()); 23128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 23138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber AString errorDetailMsg; 23148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 23151d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 23168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("index", bufferIndex); 23178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("offset", 0); 23188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("size", csd->size()); 23198ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt64("timeUs", 0ll); 23208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 23218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setPointer("errorDetailMsg", &errorDetailMsg); 23228ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 23238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return onQueueInputBuffer(msg); 23248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 23258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 23265778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) { 23277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (newState == INITIALIZED || newState == UNINITIALIZED) { 23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber delete mSoftRenderer; 23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer = NULL; 23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto.clear(); 2332f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar handleSetSurface(NULL); 23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2334671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInputFormat.clear(); 23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat.clear(); 23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagStickyError; 2339e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagIsEncoder; 2340e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 2341c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 2342251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 2343575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2344575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2345c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback.clear(); 23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2348717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (newState == UNINITIALIZED) { 2349671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // return any straggling buffers, e.g. if we got here on an error 2350671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar returnBuffersToCodec(); 2351671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 2352aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // The component is gone, mediaserver's probably back up already 2353aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // but should definitely be back up should we try to instantiate 2354aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // another component.. and the cycle continues. 2355aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags &= ~kFlagSawMediaServerDie; 2356717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2357717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber mState = newState; 23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 23612606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 23622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang updateBatteryStat(); 23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 236586b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wuvoid MediaCodec::returnBuffersToCodec(bool isReclaim) { 236686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu returnBuffersToCodecOnPort(kPortIndexInput, isReclaim); 236786b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu returnBuffersToCodecOnPort(kPortIndexOutput, isReclaim); 23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 237086b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wuvoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex, bool isReclaim) { 23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 23727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify != NULL) { 23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> msg = info->mNotify; 23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 238286b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu if (isReclaim && info->mOwnedByClient) { 238386b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu ALOGD("port %d buffer %zu still owned by client when codec is reclaimed", 238486b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu portIndex, i); 238586b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu } else { 238686b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu info->mMemRef = NULL; 238786b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu info->mOwnedByClient = false; 238886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu } 23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexInput) { 23917fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar /* no error, just returning buffers */ 23927fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar msg->setInt32("err", OK); 23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->post(); 23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23965778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23985778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].clear(); 23995778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 24005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24015778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers( 24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex, const sp<AMessage> &msg) { 24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2405609b815a3131d22da38b2f452faa9f89daad4039Andy Hung uint32_t bufferID; 2406609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mBufferID == bufferID) { 24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mNotify == NULL); 24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("reply", &info->mNotify)); 24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2417475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mFormat = 2418475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat; 24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].push_back(i); 24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber return i; 24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset; 24335778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size; 24345778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 24355778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 24365778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 24375778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("offset", &offset)); 24385778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 24395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 24405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples; 24424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples; 24434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *key; 24444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *iv; 24454b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 24464b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24474b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // We allow the simpler queueInputBuffer API to be used even in 24484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // secure mode, by fabricating a single unencrypted subSample. 24494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::SubSample ss; 2450d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker CryptoPlugin::Pattern pattern; 24514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (msg->findSize("size", &size)) { 24534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto != NULL) { 24544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfClearData = size; 24554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfEncryptedData = 0; 24564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples = &ss; 24584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples = 1; 24594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber key = NULL; 24604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber iv = NULL; 2461d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker pattern.mEncryptBlocks = 0; 2462d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker pattern.mSkipBlocks = 0; 24634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 24644b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } else { 24654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto == NULL) { 24664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber return -EINVAL; 24674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 24684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 24704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findSize("numSubSamples", &numSubSamples)); 24714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("key", (void **)&key)); 24724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("iv", (void **)&iv)); 2473d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks)); 2474d9f1f950d18b4e166b178d93260074019588c956Jeff Tinker CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks)); 24754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int32_t tmp; 24774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findInt32("mode", &tmp)); 24784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber mode = (CryptoPlugin::Mode)tmp; 24804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size = 0; 24824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber for (size_t i = 0; i < numSubSamples; ++i) { 24834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfClearData; 24844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfEncryptedData; 24854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 24864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 24874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexInput].size()) { 24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 24965778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24985778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (offset + size > info->mData->capacity()) { 24995778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 25005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25025778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> reply = info->mNotify; 25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->setRange(offset, size); 25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt64("timeUs", timeUs); 25055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25065778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_EOS) { 25075778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("eos", true); 25085778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25105778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_CODECCONFIG) { 25115778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("csd", true); 25125778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mCrypto != NULL) { 25151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (size > info->mEncryptedData->capacity()) { 25161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -ERANGE; 2517ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2518ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 25195b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg; 25205b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 25215b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 25229ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker void *dst_pointer = info->mData->base(); 25239ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker ICrypto::DestinationType dst_type = ICrypto::kDestinationTypeOpaqueHandle; 25249ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker 25259ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker if (info->mNativeHandle != NULL) { 2526c6e96a912c2cdedf853e3bd7b68c953fa818ff40Lajos Molnar dst_pointer = (void *)info->mNativeHandle->handle(); 25279ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dst_type = ICrypto::kDestinationTypeNativeHandle; 25289ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker } else if ((mFlags & kFlagIsSecure) == 0) { 25299ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dst_type = ICrypto::kDestinationTypeVmPointer; 25309ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker } 25319ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker 2532fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong ssize_t result = mCrypto->decrypt( 25339ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dst_type, 25341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber key, 25351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber iv, 25361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mode, 253718cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker pattern, 2538c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info->mSharedEncryptedBuffer, 2539c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker offset, 25404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples, 25414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples, 2542a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar dst_pointer, 25435b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg); 25441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 2545fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong if (result < 0) { 2546fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong return result; 2547ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2548ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2549fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong info->mData->setRange(0, result); 2550ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2551ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 25527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 25537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 25547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 25557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 25567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 25572d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber reply->setBuffer("buffer", info->mData); 25585778822d86b0337407514b9372562b86edfa91cdAndreas Huber reply->post(); 25595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25605b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mNotify = NULL; 25615b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 25625778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 25635778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 256590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar//static 256690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarsize_t MediaCodec::CreateFramesRenderedMessage( 256790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar std::list<FrameRenderTracker::Info> done, sp<AMessage> &msg) { 256890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar size_t index = 0; 256990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 257090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar for (std::list<FrameRenderTracker::Info>::const_iterator it = done.cbegin(); 257190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar it != done.cend(); ++it) { 257290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (it->getRenderTimeNs() < 0) { 257390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar continue; // dropped frame from tracking 257490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 257590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar msg->setInt64(AStringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs()); 257690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar msg->setInt64(AStringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs()); 257790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar ++index; 257890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 257990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar return index; 258090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar} 258190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 25825778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 25835778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 25845778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 25855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25865778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t render; 25875778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("render", &render)) { 25885778822d86b0337407514b9372562b86edfa91cdAndreas Huber render = 0; 25895778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25910e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 25925778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 25935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25955778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexOutput].size()) { 25965778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 25975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25995778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 26005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26015778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 26025778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 26035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 26045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26057bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 26067bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 26077bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 26087bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 26097bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 26107bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 261179ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou if (render && info->mData != NULL && info->mData->size() != 0) { 26125778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->setInt32("render", true); 26135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 261490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar int64_t mediaTimeUs = -1; 261590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar info->mData->meta()->findInt64("timeUs", &mediaTimeUs); 261690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 261790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar int64_t renderTimeNs = 0; 2618c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar if (!msg->findInt64("timestampNs", &renderTimeNs)) { 2619c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar // use media timestamp if client did not request a specific render timestamp 2620c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar ALOGV("using buffer PTS of %lld", (long long)mediaTimeUs); 262190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar renderTimeNs = mediaTimeUs * 1000; 2622fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2623c8edf5af010ac24a99b302a18e7b84e8b4b2b783Lajos Molnar info->mNotify->setInt64("timestampNs", renderTimeNs); 2624fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 26255778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mSoftRenderer != NULL) { 262690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar std::list<FrameRenderTracker::Info> doneFrames = mSoftRenderer->render( 2627475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mData->data(), info->mData->size(), 262890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar mediaTimeUs, renderTimeNs, NULL, info->mFormat); 262990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar 263090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar // if we are running, notify rendered frames 263190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (!doneFrames.empty() && mState == STARTED && mOnFrameRenderedNotification != NULL) { 263290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar sp<AMessage> notify = mOnFrameRenderedNotification->dup(); 263390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar sp<AMessage> data = new AMessage; 263490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar if (CreateFramesRenderedMessage(doneFrames, data)) { 263590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar notify->setMessage("data", data); 263690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar notify->post(); 263790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 263890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar } 26395778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 26405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 26415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26425778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->post(); 26435778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 26445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26455778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 26465778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 26475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26485778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 26495778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 26505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26515778822d86b0337407514b9372562b86edfa91cdAndreas Huber List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 26525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26535778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (availBuffers->empty()) { 26545778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EAGAIN; 26555778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 26565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26575778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index = *availBuffers->begin(); 26585778822d86b0337407514b9372562b86edfa91cdAndreas Huber availBuffers->erase(availBuffers->begin()); 26595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26605778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 26615778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(!info->mOwnedByClient); 26627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 26637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 26647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = true; 266503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar 266603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar // set image-data 266703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat != NULL) { 266803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar sp<ABuffer> imageData; 266903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findBuffer("image-data", &imageData)) { 267003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setBuffer("image-data", imageData); 267103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 267203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar int32_t left, top, right, bottom; 267303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) { 267403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setRect("crop-rect", left, top, right, bottom); 267503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 267603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 26777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 26785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return index; 26805778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 26815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 26821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::connectToSurface(const sp<Surface> &surface) { 26831dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = OK; 26841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (surface != NULL) { 2685b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar uint64_t oldId, newId; 2686098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar if (mSurface != NULL 2687b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar && surface->getUniqueId(&newId) == NO_ERROR 2688b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar && mSurface->getUniqueId(&oldId) == NO_ERROR 2689b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar && newId == oldId) { 2690b9fa58afa4c7772fe3c4cfdea9e45bc85cf43537Lajos Molnar ALOGI("[%s] connecting to the same surface. Nothing to do.", mComponentName.c_str()); 2691098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar return ALREADY_EXISTS; 2692098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar } 2693098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar 26941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA); 2695098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar if (err == OK) { 2696264bac95912efe121d6a60026612617f04f42966Lajos Molnar // Require a fresh set of buffers after each connect by using a unique generation 2697264bac95912efe121d6a60026612617f04f42966Lajos Molnar // number. Rely on the fact that max supported process id by Linux is 2^22. 2698264bac95912efe121d6a60026612617f04f42966Lajos Molnar // PID is never 0 so we don't have to worry that we use the default generation of 0. 2699264bac95912efe121d6a60026612617f04f42966Lajos Molnar // TODO: come up with a unique scheme if other producers also set the generation number. 2700264bac95912efe121d6a60026612617f04f42966Lajos Molnar static uint32_t mSurfaceGeneration = 0; 2701264bac95912efe121d6a60026612617f04f42966Lajos Molnar uint32_t generation = (getpid() << 10) | (++mSurfaceGeneration & ((1 << 10) - 1)); 2702264bac95912efe121d6a60026612617f04f42966Lajos Molnar surface->setGenerationNumber(generation); 2703264bac95912efe121d6a60026612617f04f42966Lajos Molnar ALOGI("[%s] setting surface generation to %u", mComponentName.c_str(), generation); 2704264bac95912efe121d6a60026612617f04f42966Lajos Molnar 2705264bac95912efe121d6a60026612617f04f42966Lajos Molnar // HACK: clear any free buffers. Remove when connect will automatically do this. 2706264bac95912efe121d6a60026612617f04f42966Lajos Molnar // This is needed as the consumer may be holding onto stale frames that it can reattach 2707264bac95912efe121d6a60026612617f04f42966Lajos Molnar // to this surface after disconnect/connect, and those free frames would inherit the new 2708264bac95912efe121d6a60026612617f04f42966Lajos Molnar // generation number. Disconnecting after setting a unique generation prevents this. 2709264bac95912efe121d6a60026612617f04f42966Lajos Molnar native_window_api_disconnect(surface.get(), NATIVE_WINDOW_API_MEDIA); 2710264bac95912efe121d6a60026612617f04f42966Lajos Molnar err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA); 2711264bac95912efe121d6a60026612617f04f42966Lajos Molnar } 2712264bac95912efe121d6a60026612617f04f42966Lajos Molnar 2713264bac95912efe121d6a60026612617f04f42966Lajos Molnar if (err != OK) { 27141dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err); 27151dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 27161dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 2717098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar // do not return ALREADY_EXISTS unless surfaces are the same 2718098446ae4100dfd989c452bb67133559aa892cd3Lajos Molnar return err == ALREADY_EXISTS ? BAD_VALUE : err; 27191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 27207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 27211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::disconnectFromSurface() { 27221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = OK; 2723f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar if (mSurface != NULL) { 2724264bac95912efe121d6a60026612617f04f42966Lajos Molnar // Resetting generation is not technically needed, but there is no need to keep it either 2725264bac95912efe121d6a60026612617f04f42966Lajos Molnar mSurface->setGenerationNumber(0); 27261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); 27277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 27281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGW("native_window_api_disconnect returned an error: %s (%d)", strerror(-err), err); 27297541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 27301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // assume disconnected even on error 2731f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar mSurface.clear(); 27327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 27331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 27341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 27357541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 27361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::handleSetSurface(const sp<Surface> &surface) { 27371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = OK; 27381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mSurface != NULL) { 27391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar (void)disconnectFromSurface(); 27401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 2741f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar if (surface != NULL) { 27421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = connectToSurface(surface); 27431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == OK) { 27441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mSurface = surface; 27457541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 27467541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 27471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 27487541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber} 27497541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 2750c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() { 2751c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2752c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) { 2753c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2754c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_INPUT_AVAILABLE); 2755c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2756c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2757c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2758c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2759c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2760c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() { 2761c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2762c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) { 2763c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang const sp<ABuffer> &buffer = 2764c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mPortBuffers[kPortIndexOutput].itemAt(index).mData; 2765c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2766c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE); 2767c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2768c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("offset", buffer->offset()); 2769c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("size", buffer->size()); 2770c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2771c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int64_t timeUs; 2772c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2773c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2774c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt64("timeUs", timeUs); 2775c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2776c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t omxFlags; 2777c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 2778c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2779c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang uint32_t flags = 0; 2780c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 2781c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_SYNCFRAME; 2782c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2783c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 2784c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_CODECCONFIG; 2785c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2786c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_EOS) { 2787c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_EOS; 2788c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2789c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2790c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("flags", flags); 2791c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2792c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2793c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2794c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2795c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2796749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) { 2797c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2798c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2799c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_ERROR); 2800c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("err", err); 2801749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setInt32("actionCode", actionCode); 2802749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang 2803749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang if (detail != NULL) { 2804749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setString("detail", detail); 2805749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang } 2806c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2807c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2808c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2809c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2810c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2811c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() { 2812c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2813c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2814c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED); 2815c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("format", mOutputFormat); 2816c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2817c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2818c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2819c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2820c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2821575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() { 2822575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (mActivityNotify == NULL) { 2823575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber return; 2824575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2825575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2826e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang bool isErrorOrOutputChanged = 2827e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang (mFlags & (kFlagStickyError 2828575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber | kFlagOutputBuffersChanged 2829e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang | kFlagOutputFormatChanged)); 2830e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2831e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged 2832575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexInput].empty() 2833575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexOutput].empty()) { 2834e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("input-buffers", 2835e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexInput].size()); 2836e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2837e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged) { 2838e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang // we want consumer to dequeue as many times as it can 2839e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", INT32_MAX); 2840e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } else { 2841e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", 2842e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexOutput].size()); 2843e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } 2844575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify->post(); 2845575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2846575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2847575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 2848575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2849a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 28501d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 2851a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber msg->setMessage("params", params); 2852a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2853a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> response; 2854a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return PostAndAwaitResponse(msg, &response); 2855a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2856a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2857a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 2858a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber mCodec->signalSetParameters(params); 2859a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2860a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return OK; 2861a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2862a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2863e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData( 2864e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const sp<ABuffer> &buffer) { 2865e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber AString mime; 2866e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber CHECK(mOutputFormat->findString("mime", &mime)); 2867e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2868e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 2869e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Codec specific data should be SPS and PPS in a single buffer, 2870e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // each prefixed by a startcode (0x00 0x00 0x00 0x01). 2871e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // We separate the two and put them into the output format 2872e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // under the keys "csd-0" and "csd-1". 2873e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2874e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber unsigned csdIndex = 0; 2875e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2876e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *data = buffer->data(); 2877e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t size = buffer->size(); 2878e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2879e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *nalStart; 2880e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t nalSize; 2881e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 2882e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber sp<ABuffer> csd = new ABuffer(nalSize + 4); 2883e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data(), "\x00\x00\x00\x01", 4); 2884e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data() + 4, nalStart, nalSize); 2885e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2886e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer( 2887a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes AStringPrintf("csd-%u", csdIndex).c_str(), csd); 2888e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2889e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ++csdIndex; 2890e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2891e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2892e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (csdIndex != 2) { 2893e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return ERROR_MALFORMED; 2894e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2895e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 2896e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // For everything else we just stash the codec specific data into 2897e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the output format as a single piece of csd under "csd-0". 2898e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer("csd-0", buffer); 2899e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2900e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2901e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return OK; 2902e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} 2903e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 29042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() { 29053f273d10817ddb2f792ae043de692efcdf1988aeWei Jia if (!mIsVideo) { 29063f273d10817ddb2f792ae043de692efcdf1988aeWei Jia return; 29073f273d10817ddb2f792ae043de692efcdf1988aeWei Jia } 29082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 29093f273d10817ddb2f792ae043de692efcdf1988aeWei Jia if (mState == CONFIGURED && !mBatteryStatNotified) { 29103f273d10817ddb2f792ae043de692efcdf1988aeWei Jia BatteryNotifier::getInstance().noteStartVideo(); 29112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = true; 29122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else if (mState == UNINITIALIZED && mBatteryStatNotified) { 29133f273d10817ddb2f792ae043de692efcdf1988aeWei Jia BatteryNotifier::getInstance().noteStopVideo(); 29142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = false; 29152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 29162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 29172606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 29185778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 2919