MediaCodec.cpp revision 8f9dd872366f54b6260506c75c3d0cc3f9f73f81
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 242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IBatteryStats.h> 25c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h> 2667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <binder/IPCThreadState.h> 272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h> 28c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/MemoryDealer.h> 291a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h> 30ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h> 3167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h> 325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h> 345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h> 355b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h> 36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h> 375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h> 387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h> 392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h> 406f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h> 41e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h> 425778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h> 43744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h> 445778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h> 455778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h> 462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h> 472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h> 482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h> 49e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 505778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android { 515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic inline int getCallingPid() { 5367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return IPCThreadState::self()->getCallingPid(); 5467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 5567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 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) { 6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (err == OMX_ErrorInsufficientResources); 6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2; 6567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient { 6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {} 6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu virtual bool reclaimResource() { 7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<MediaCodec> codec = mMediaCodec.promote(); 7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (codec == NULL) { 7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // codec is already gone. 7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return true; 7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err = codec->release(); 7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerClient failed to release codec with err %d", err); 7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 7967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (err == OK); 8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 818f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu 828f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu virtual String8 getName() { 838f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu String8 ret; 848f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu sp<MediaCodec> codec = mMediaCodec.promote(); 858f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu if (codec == NULL) { 868f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu // codec is already gone. 878f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu return ret; 888f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 898f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu 908f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu AString name; 918f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu if (codec->getName(&name) == OK) { 928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu ret.setTo(name.c_str()); 938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu return ret; 958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 9667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 9767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected: 9867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu virtual ~ResourceManagerClient() {} 9967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate: 10167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu wp<MediaCodec> mMediaCodec; 10267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient); 10467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}; 10567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 1062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> { 1072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier(); 108d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang virtual ~BatteryNotifier(); 1092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStartVideo(); 1112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStopVideo(); 1122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStartAudio(); 1132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStopAudio(); 114d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang void onBatteryStatServiceDied(); 1152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate: 117d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang struct DeathNotifier : public IBinder::DeathRecipient { 118d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang DeathNotifier() {} 119d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang virtual void binderDied(const wp<IBinder>& /*who*/) { 120d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang BatteryNotifier::getInstance().onBatteryStatServiceDied(); 121d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 122d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang }; 123d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 124d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex mLock; 1252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang int32_t mVideoRefCount; 1262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang int32_t mAudioRefCount; 1272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang sp<IBatteryStats> mBatteryStatService; 128d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<DeathNotifier> mDeathNotifier; 129d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 130d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> getBatteryService_l(); 131d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 132d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier); 1332606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}; 1342606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1352606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier) 1362606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() : 1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount(0), 1392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount(0) { 140d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 141d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 142d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() { 143d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mBatteryStatService != NULL) { 144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return mBatteryStatService; 145d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 146d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // get battery service from service manager 1472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang const sp<IServiceManager> sm(defaultServiceManager()); 1482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (sm != NULL) { 1492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang const String16 name("batterystats"); 150d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService = 151d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang interface_cast<IBatteryStats>(sm->getService(name)); 1522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mBatteryStatService == NULL) { 1532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGE("batterystats service unavailable!"); 154d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return NULL; 155d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 156d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier = new DeathNotifier(); 157d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (IInterface::asBinder(mBatteryStatService)-> 158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang linkToDeath(mDeathNotifier) != OK) { 159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService.clear(); 160d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier.clear(); 161d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return NULL; 1622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 163d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // notify start now if media already started 164d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount > 0) { 165d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService->noteStartVideo(AID_MEDIA); 166d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount > 0) { 168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService->noteStartAudio(AID_MEDIA); 169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 171d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return mBatteryStatService; 172d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 173d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 174d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() { 175d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mDeathNotifier != NULL) { 176d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang IInterface::asBinder(mBatteryStatService)-> 177d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang unlinkToDeath(mDeathNotifier); 1782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() { 182d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 183d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 184d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount == 0 && batteryService != NULL) { 185d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStartVideo(AID_MEDIA); 1862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount++; 1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() { 191d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 1922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mVideoRefCount == 0) { 1932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGW("BatteryNotifier::noteStop(): video refcount is broken!"); 1942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang return; 1952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount--; 198d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 199d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount == 0 && batteryService != NULL) { 200d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStopVideo(AID_MEDIA); 2012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 2032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 2042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() { 205d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 206d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 207d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount == 0 && batteryService != NULL) { 208d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStartAudio(AID_MEDIA); 2092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount++; 2112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 2122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 2132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() { 214d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 2152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mAudioRefCount == 0) { 2162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!"); 2172606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang return; 2182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 2202606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount--; 221d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 222d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount == 0 && batteryService != NULL) { 223d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStopAudio(AID_MEDIA); 2242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 226d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 227d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() { 228d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 229d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService.clear(); 230d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier.clear(); 231d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // Do not reset mVideoRefCount and mAudioRefCount here. The ref 232d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // counting is independent of the battery service availability. 233d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // We need this if battery service becomes available after media 234d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // started. 235d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 236d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 23767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() { 23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() { 24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService != NULL) { 24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu IInterface::asBinder(mService)->unlinkToDeath(this); 24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() { 24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IServiceManager> sm = defaultServiceManager(); 24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IBinder> binder = sm->getService(String16("media.resource_manager")); 24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService = interface_cast<IResourceManagerService>(binder); 25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("Failed to get ResourceManagerService"); 25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 254e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu IInterface::asBinder(mService)->linkToDeath(this); 25567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) { 25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerService died."); 25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService.clear(); 26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource( 26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int pid, 26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int64_t clientId, 26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const sp<IResourceManagerClient> client, 26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const Vector<MediaResource> &resources) { 26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService->addResource(pid, clientId, client, resources); 27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) { 27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService->removeResource(clientId); 28167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 28267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 28367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource( 28467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int callingPid, const Vector<MediaResource> &resources) { 28567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 28767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return false; 28867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 28967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return mService->reclaimResource(callingPid, resources); 29067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 29167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 2935778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType( 294251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) { 2955778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = new MediaCodec(looper); 2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 297251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(mime, true /* nameIsType */, encoder); 298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 299251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 300251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 301251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 3055778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName( 306251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const sp<ALooper> &looper, const char *name, status_t *err) { 3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = new MediaCodec(looper); 3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 309251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */); 310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 311251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 312251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 313251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3165778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper) 3175778822d86b0337407514b9372562b86edfa91cdAndreas Huber : mState(UNINITIALIZED), 3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper(looper), 31992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar mCodec(NULL), 3207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID(0), 3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags(0), 322251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError(OK), 3235778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer(NULL), 324ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mResourceManagerClient(new ResourceManagerClient(this)), 325ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mResourceManagerService(new ResourceManagerServiceProxy()), 3262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified(false), 3272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mIsVideo(false), 32867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoWidth(0), 32967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoHeight(0), 3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputTimeoutGeneration(0), 3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID(0), 3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputTimeoutGeneration(0), 3336507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mDequeueOutputReplyID(0), 3343d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHaveInputSurface(false), 3353d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers(false) { 3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3385778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() { 3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, UNINITIALIZED); 34067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 3445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse( 3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &msg, sp<AMessage> *response) { 3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = msg->postAndAwaitResponse(response); 3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!(*response)->findInt32("err", &err)) { 3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = OK; 3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3565778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3575778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 359c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static 3603f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) { 361c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 362c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->setInt32("err", err); 363c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 364c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 365c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 366dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) { 36767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->init(); 36867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 369671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // save init parameters for reset 370671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitName = name; 371671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitNameIsType = nameIsType; 372671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitIsEncoder = encoder; 373671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Current video decoders do not return from OMX_FillThisBuffer 3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber // quickly, violating the OpenMAX specs, until that is remedied 3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber // we need to invest in an extra looper to free the main event 3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber // queue. 378744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 379bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) { 380744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mCodec = new ACodec; 381744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else if (!nameIsType 382bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung && !strncasecmp(name.c_str(), "android.filter.", 15)) { 383744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mCodec = new MediaFilter; 384744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else { 385744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return NAME_NOT_FOUND; 386744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 387744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 38867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu bool secureCodec = false; 389dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) { 39067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 3916f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } else { 3926f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen AString tmp = name; 3936f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (tmp.endsWith(".secure")) { 39467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu secureCodec = true; 3956f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen tmp.erase(tmp.size() - 7, 7); 3966f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 39760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); 3986f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); 3996f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (codecIdx >= 0) { 40060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); 40160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<AString> mimes; 40260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar info->getSupportedMimes(&mimes); 40360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t i = 0; i < mimes.size(); i++) { 40460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (mimes[i].startsWith("video/")) { 40567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 40660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar break; 4076f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4086f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4096f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 41267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 41367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // video codec needs dedicated looper 4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mCodecLooper == NULL) { 4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper = new ALooper; 4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->setName("CodecLooper"); 4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->registerHandler(mCodec); 4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(mCodec); 4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(this); 4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4271d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this)); 4285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4291d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatInit, this); 4305778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setString("name", name); 4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("nameIsType", nameIsType); 4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("encoder", encoder); 4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 43767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 43867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 43967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec; 44067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(type), 1)); 44167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 44267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 44467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 44567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 44667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 44767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 44867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 44967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 45067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 45167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 45267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 45367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 45467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 45567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) { 4591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetCallback, this); 460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("callback", callback); 461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response; 463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang return PostAndAwaitResponse(msg, &response); 464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 4665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure( 4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &format, 4681a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian const sp<Surface> &nativeWindow, 4691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const sp<ICrypto> &crypto, 4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags) { 4711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigure, this); 4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 47367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 47467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("width", &mVideoWidth); 47567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("height", &mVideoHeight); 47667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 47767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setMessage("format", format); 4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nativeWindow != NULL) { 4821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber msg->setObject( 4831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber "native-window", 4841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber new NativeWindowWrapper(nativeWindow)); 4851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 4861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 4871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (crypto != NULL) { 4881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber msg->setPointer("crypto", crypto.get()); 4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 49167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // save msg for reset 49267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mConfigureMsg = msg; 493f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 49467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 49567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 49667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = (mFlags & kFlagIsSecure) ? 49767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu kResourceSecureCodec : kResourceNonSecureCodec; 49867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(type), 1)); 49967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 50067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 50167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1)); 50267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 50367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 50467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 509f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 51067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 51167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 51267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK && err != INVALID_OPERATION) { 51367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // MediaCodec now set state to UNINITIALIZED upon any fatal error. 51467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // To maintain backward-compatibility, do a reset() to put codec 51567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // back into INITIALIZED state. 51667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // But don't reset if the err is INVALID_OPERATION, which means 51767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the configure failure is due to wrong state. 51867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 51967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("configure failed with err 0x%08x, resetting...", err); 52067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu reset(); 52167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 52367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 525f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang } 526f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang return err; 5275778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface( 5307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 5311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this); 5327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 5337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 5347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = PostAndAwaitResponse(msg, &response); 5357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (err == NO_ERROR) { 5367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // unwrap the sp<IGraphicBufferProducer> 5377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 5387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden bool found = response->findObject("input-surface", &obj); 5397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(found); 5407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<BufferProducerWrapper> wrapper( 5417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden static_cast<BufferProducerWrapper*>(obj.get())); 5427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden *bufferProducer = wrapper->getBufferProducer(); 5437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 5447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGW("createInputSurface failed, err=%d", err); 5457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 5467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return err; 5477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 5487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 54967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() { 55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mIsVideo) { 55167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return 0; 55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 55367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu uint64_t size = 0; 55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]); 55667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (size_t i = 0; i < portNum; ++i) { 55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // TODO: this is just an estimation, we should get the real buffer size from ACodec. 55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2; 55967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 56067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return size; 56167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 56267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::addResource(const char *type, uint64_t value) { 56467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(type), value)); 56667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->addResource( 56767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources); 56867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 56967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 5705778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() { 5711d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, this); 5725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 57367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 57467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 57567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = (mFlags & kFlagIsSecure) ? 57667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu kResourceSecureCodec : kResourceNonSecureCodec; 57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(type), 1)); 57867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 58067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1)); 58167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 58467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 58567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 58667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 58767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Recover codec from previous error before retry start. 58867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = reset(); 58967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 59067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to reset codec"); 59167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 59267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(mConfigureMsg, &response); 59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to configure codec"); 59767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 60067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 60167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 60267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 60767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 6085778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6105778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() { 6111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, this); 6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 6145778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 6155778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 617c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() { 6181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRelease, this); 619c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 620c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response; 621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return PostAndAwaitResponse(msg, &response); 622c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 624671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() { 625671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar /* When external-facing MediaCodec object is created, 626671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar it is already initialized. Thus, reset is essentially 627671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar release() followed by init(), plus clearing the state */ 628671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 629671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar status_t err = release(); 630671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 631671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // unregister handlers 632671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodec != NULL) { 633671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodecLooper != NULL) { 634671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodecLooper->unregisterHandler(mCodec->id()); 635671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } else { 636671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(mCodec->id()); 637671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 638671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodec = NULL; 639671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 640671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(id()); 641671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 642671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mFlags = 0; // clear all flags 643251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 644671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 645671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // reset state not reset by setState(UNINITIALIZED) 646671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mReplyID = 0; 647671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputReplyID = 0; 648671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputReplyID = 0; 649671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputTimeoutGeneration = 0; 650671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputTimeoutGeneration = 0; 651671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mHaveInputSurface = false; 652671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 653671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (err == OK) { 654dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung err = init(mInitName, mInitNameIsType, mInitIsEncoder); 655671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 656671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar return err; 657671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar} 658671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 6595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer( 6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index, 6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset, 6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size, 6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t presentationTimeUs, 6645b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 6655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 6665b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 6675b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 6685b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 6695b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 6701d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 6715778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 6725778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("offset", offset); 6735778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("size", size); 6745778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 6765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 6805778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer( 6834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t index, 6844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t offset, 6854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples, 6864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples, 6874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t key[16], 6884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t iv[16], 6894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode, 6904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int64_t presentationTimeUs, 6915b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 6925b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 6935b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 6945b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 6955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 6965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 6971d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 6984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("index", index); 6994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("offset", offset); 7004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("subSamples", (void *)subSamples); 7014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("numSubSamples", numSubSamples); 7024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("key", (void *)key); 7034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("iv", (void *)iv); 7044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("mode", mode); 7054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 7064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("flags", flags); 7075b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 7084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber sp<AMessage> response; 7105b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber status_t err = PostAndAwaitResponse(msg, &response); 7115b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7125b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber return err; 7134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber} 7144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 7161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this); 7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7195778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer( 7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *index, 7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *offset, 7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *size, 7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t *presentationTimeUs, 7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t *flags, 7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs) { 7371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this); 7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("offset", offset)); 7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("size", size)); 7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt64("timeUs", presentationTimeUs)); 7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt32("flags", (int32_t *)flags)); 7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 7561d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("render", true); 7595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7605778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 764fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) { 7651d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 766fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setSize("index", index); 767fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt32("render", true); 768fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt64("timestampNs", timestampNs); 769fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 770fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar sp<AMessage> response; 771fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar return PostAndAwaitResponse(msg, &response); 772fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar} 773fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 7745778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) { 7751d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() { 7831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this); 7847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 7857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 7867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return PostAndAwaitResponse(msg, &response); 7877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 7887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 7895778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 7901d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this); 7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findMessage("format", format)); 7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const { 8041d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this); 805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 806e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> response; 807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar status_t err; 808e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 809e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return err; 810e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(response->findMessage("format", format)); 813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return OK; 815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar} 816e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 817717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const { 8181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetName, this); 819717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 820717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response; 821717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo status_t err; 822717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 823717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return err; 824717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 825717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 826717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(response->findString("name", name)); 827717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 828717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return OK; 829717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo} 830717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 831e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const { 832e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 833e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("portIndex", kPortIndexInput); 834e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setPointer("buffers", buffers); 835e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("widevine", true); 836e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 837e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> response; 838e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar return PostAndAwaitResponse(msg, &response); 839e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar} 840e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 8415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 8421d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexInput); 8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8505778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 8511d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexOutput); 8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) { 8607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 8617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, buffer, &format); 8627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) { 8657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> buffer; 8667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, &buffer, format); 8677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) { 8707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexInput, index, buffer, &format); 8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const { 8750e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar return mState == STARTED || mState == FLUSHED; 8760e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar} 8770e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar 8787bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat( 8797bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar size_t portIndex, size_t index, 8807bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> *buffer, sp<AMessage> *format) { 8817bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // use mutex instead of a context switch 8827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8837bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar buffer->clear(); 8847bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar format->clear(); 8850e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 8867bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return INVALID_OPERATION; 8877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 8887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8897bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we do not want mPortBuffers to change during this section 8907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we also don't want mOwnedByClient to change during this 8917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 8927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 8937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar if (index < buffers->size()) { 8947bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo &info = buffers->itemAt(index); 8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar if (info.mOwnedByClient) { 8960837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar // by the time buffers array is initialized, crypto is set 8970837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar if (portIndex == kPortIndexInput && mCrypto != NULL) { 8980837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar *buffer = info.mEncryptedData; 8990837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar } else { 9000837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar *buffer = info.mData; 9010837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar } 9027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar *format = info.mFormat; 9037bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 9047bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 9057bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return OK; 9067bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9077bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9085778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() { 9091d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFlush, this); 9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 9135778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 915496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() { 9161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatRequestIDRFrame, this))->post(); 917496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 918496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber return OK; 919496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 920496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 921575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 9221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this); 923575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->setMessage("notify", notify); 924575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->post(); 925575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 926575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber//////////////////////////////////////////////////////////////////////////////// 9285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9295778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() { 9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueInputPending) { 931c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION); 9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueOutputPending) { 939c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION); 9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 9435778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9473f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 9480e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueInputPending))) { 950c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 952251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 953251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 954251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return true; 9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9713f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INVALID_OPERATION); 977251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 978251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung response->setInt32("err", getStickyError()); 9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputBuffersChanged) { 9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); 9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputFormatChanged) { 9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INFO_FORMAT_CHANGED); 9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexOutput); 9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<ABuffer> &buffer = 9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[kPortIndexOutput].itemAt(index).mData; 9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("offset", buffer->offset()); 9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("size", buffer->size()); 9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt64("timeUs", timeUs); 10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags = 0; 10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_SYNCFRAME; 10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_CODECCONFIG; 10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_EOS) { 10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_EOS; 10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("flags", flags); 10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10275778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (msg->what()) { 10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatCodecNotify: 10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t what; 10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("what", &what)); 10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (what) { 103592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatError: 10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1037251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung int32_t err, actionCode; 1038251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("err", &err)); 1039251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("actionCode", &actionCode)); 10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10419e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen ALOGE("Codec reported err %#x, actionCode %d, while in state %d", 10429e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen err, actionCode, mState); 1043251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err == DEAD_OBJECT) { 1044aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags |= kFlagSawMediaServerDie; 104552dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 1046aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1047aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 10485530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia bool sendErrorResponse = true; 10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (mState) { 10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber case INITIALIZING: 10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(UNINITIALIZED); 10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber case CONFIGURING: 10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1059c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1060c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : INITIALIZED); 10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTING: 10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1066c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1067c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : CONFIGURED); 10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STOPPING: 1072c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case RELEASING: 10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Ignore the error, assuming we'll still get 10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber // the shutdown complete notification. 10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10775530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 107803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 1079aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 108003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // MediaServer died, there definitely won't 108103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // be a shutdown complete notification after 108203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // all. 108303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 108403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // note that we're directly going from 108503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // STOPPING->UNINITIALIZED, instead of the 108603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // usual STOPPING->INITIALIZED state. 108703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber setState(UNINITIALIZED); 10886e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (mState == RELEASING) { 10896e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 10906e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 109103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber (new AMessage)->postReply(mReplyID); 109203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber } 10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber case FLUSHING: 10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10989e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen if (actionCode == ACTION_CODE_FATAL) { 10999e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState(UNINITIALIZED); 11009e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } else { 11019e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState( 11029e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen (mFlags & kFlagIsAsync) ? FLUSHED : STARTED); 11039e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } 11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar case FLUSHED: 11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTED: 11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11105530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1113575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 1116c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1117c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1121251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1129c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11335778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11355530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1137251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1138575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1139c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1140251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung // actionCode in an uninitialized state is always fatal. 1141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (mState == UNINITIALIZED) { 1142251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung actionCode = ACTION_CODE_FATAL; 1143251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1144c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1145251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1146251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1147251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1148251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1149251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1152251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1153251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1154251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1155251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1156c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11615530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (sendErrorResponse) { 1162251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(mReplyID, err); 11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 116792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentAllocated: 11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, INITIALIZING); 11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZED); 117152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags |= kFlagIsComponentAllocated; 11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1173717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->findString("componentName", &mComponentName)); 11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1175717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.startsWith("OMX.google.")) { 11763a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 11775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 11783a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags &= ~kFlagUsesSoftwareRenderer; 11795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 118167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu String8 resourceType; 1182717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.endsWith(".secure")) { 11831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags |= kFlagIsSecure; 118467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resourceType = String8(kResourceSecureCodec); 11851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 11861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags &= ~kFlagIsSecure; 118767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resourceType = String8(kResourceNonSecureCodec); 11881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 118967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu addResource(resourceType, 1); 11901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 11915778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 119592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentConfigured: 11965778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, CONFIGURING); 11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11996507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden // reset input surface flag 12006507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = false; 12016507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 1202e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("input-format", &mInputFormat)); 1203e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("output-format", &mOutputFormat)); 1204e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 12053a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar int32_t usingSwRenderer; 12063a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer) 12073a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar && usingSwRenderer) { 12083a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 12093a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 12102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang setState(CONFIGURED); 12115778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 12125778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 121592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatInputSurfaceCreated: 12167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 121792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to initiateCreateInputSurface() 12187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = NO_ERROR; 12197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response = new AMessage(); 12207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (!msg->findInt32("err", &err)) { 12217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 12227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden msg->findObject("input-surface", &obj); 12237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(obj != NULL); 12247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setObject("input-surface", obj); 12256507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = true; 12267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 12277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 12287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 12307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 12317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 123392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatSignaledInputEOS: 12347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 123592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to signalEndOfInputStream() 12367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response = new AMessage(); 12377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err; 12387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (msg->findInt32("err", &err)) { 12397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 12407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 12427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 12437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 12457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 124692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatBuffersAllocated: 12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 12487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("%s buffers allocated", 12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber portIndex == kPortIndexInput ? "input" : "output"); 12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput 12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber || portIndex == kPortIndexOutput); 12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[portIndex].clear(); 12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1262eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber sp<RefBase> obj; 1263eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber CHECK(msg->findObject("portDesc", &obj)); 1264eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 126592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar sp<CodecBase::PortDescription> portDesc = 126692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar static_cast<CodecBase::PortDescription *>(obj.get()); 12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1268eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber size_t numBuffers = portDesc->countBuffers(); 12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1270c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker size_t totalSize = 0; 1271c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker for (size_t i = 0; i < numBuffers; ++i) { 1272c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (portIndex == kPortIndexInput && mCrypto != NULL) { 1273c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker totalSize += portDesc->bufferAt(i)->capacity(); 1274c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1275c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1276c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1277c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (totalSize) { 1278c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker mDealer = new MemoryDealer(totalSize, "MediaCodec"); 1279c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1280c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1281eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber for (size_t i = 0; i < numBuffers; ++i) { 12825778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo info; 1283eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mBufferID = portDesc->bufferIDAt(i); 12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber info.mOwnedByClient = false; 1285eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mData = portDesc->bufferAt(i); 12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (portIndex == kPortIndexInput && mCrypto != NULL) { 1288c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sp<IMemory> mem = mDealer->allocate(info.mData->capacity()); 1289ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info.mEncryptedData = 1290c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker new ABuffer(mem->pointer(), info.mData->capacity()); 1291c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info.mSharedEncryptedBuffer = mem; 1292ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 1293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffers->push_back(info); 12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexOutput) { 12985778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState == STARTING) { 12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We're always allocating output buffers after 13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber // allocating input buffers, so this is a good 13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber // indication that now all buffers are allocated. 130267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 130367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu addResource(kResourceGraphicMemory, getGraphicBufferSize()); 130467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTED); 13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 13085778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagOutputBuffersChanged; 1309575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 13105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 131592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatOutputFormatChanged: 13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("codec output format changed"); 13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1319475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mSoftRenderer == NULL && 1320475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mNativeWindow != NULL && 13213a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar (mFlags & kFlagUsesSoftwareRenderer)) { 13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString mime; 13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("mime", &mime)); 13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1325475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mime.startsWithIgnoreCase("video/")) { 1326475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mSoftRenderer = new SoftwareRenderer(mNativeWindow); 13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat = msg; 1331e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1332e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagIsEncoder) { 1333e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Before we announce the format change we should 1334e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // collect codec specific data and amend the output 1335e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format as necessary. 1336e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagGatherCodecSpecificData; 1337c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagIsAsync) { 1338c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1339e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 1340e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagOutputFormatChanged; 1341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber postActivityNotificationIfPossible(); 1342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 13432514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 13442514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker // Notify mCrypto of video resolution changes 13452514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker if (mCrypto != NULL) { 13468140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar int32_t left, top, right, bottom, width, height; 13478140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { 13488140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(right - left + 1, bottom - top + 1); 13498140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } else if (mOutputFormat->findInt32("width", &width) 13508140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar && mOutputFormat->findInt32("height", &height)) { 13518140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(width, height); 13528140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } 13532514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 13542514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 135892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFillThisBuffer: 13595778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13605778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexInput, msg); 13615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1362c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1363c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1364c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (!mCSD.empty()) { 13708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 13718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK_GE(index, 0); 13728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // If codec specific data had been specified as 13748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // part of the format in the call to configure and 13758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // if there's more csd left, we submit it here 13768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // clients only get access to input buffers once 13778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // this data has been exhausted. 13788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber status_t err = queueCSDInputBuffer(index); 13808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (err != OK) { 13828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ALOGE("queueCSDInputBuffer failed w/ error %d", 13838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber err); 13848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1385251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1386575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1387575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 13888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber cancelPendingDequeueOperations(); 13898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 13908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 13918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 13928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1393c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 13946e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (!mHaveInputSurface) { 13953d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mState == FLUSHED) { 13963d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = true; 13973d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } else { 13983d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 13993d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 14006e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1401c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueInputPending) { 14025778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 1407575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1408575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 141392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatDrainThisBuffer: 14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexOutput, msg); 14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1417c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1418c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1419c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14242d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 14252d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14275778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 14285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", &omxFlags)); 14295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("omxFlags", omxFlags); 14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagGatherCodecSpecificData) { 1433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // This is the very first output buffer after a 1434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format change was signalled, it'll either contain 1435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the one piece of codec specific data we can expect 1436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // or there won't be codec specific data. 1437e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 1438e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber status_t err = 1439e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber amendOutputFormatWithCodecSpecificData(buffer); 1440e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1441e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (err != OK) { 1442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ALOGE("Codec spit out malformed codec " 1443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber "specific data!"); 1444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 1448c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagOutputFormatChanged; 1452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputBufferAvailable(); 1457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueOutputPending) { 14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 14595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 1463575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1464575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1466575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 147092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatEOS: 14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We already notify the client of this by using the 14735778822d86b0337407514b9372562b86edfa91cdAndreas Huber // corresponding flag in "onOutputBufferReady". 14745778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 147792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatShutdownCompleted: 14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1479c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == STOPPING) { 1480c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(INITIALIZED); 1481c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } else { 1482c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK_EQ(mState, RELEASING); 1483c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(UNINITIALIZED); 14846e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 1485c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 148652dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 148867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 148967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 149492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFlushCompleted: 14955778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14965530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (mState != FLUSHING) { 14975530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia ALOGW("received FlushCompleted message in state %d", 14985530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia mState); 14995530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia break; 15005530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia } 15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15020e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mFlags & kFlagIsAsync) { 15030e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(FLUSHED); 15040e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else { 15050e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(STARTED); 15060e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 15070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } 15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 15105778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 15145778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatInit: 15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15213f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != UNINITIALIZED) { 1525c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZING); 15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString name; 15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("name", &name)); 15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t nameIsType; 15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t encoder = false; 15370db280176bd3277e3256252d063f3712b1905ba9Andreas Huber CHECK(msg->findInt32("nameIsType", &nameIsType)); 15380db280176bd3277e3256252d063f3712b1905ba9Andreas Huber if (nameIsType) { 15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("encoder", &encoder)); 15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format = new AMessage; 15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("mime", name.c_str()); 15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", encoder); 15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("componentName", name.c_str()); 15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateAllocateComponent(format); 15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1555c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang case kWhatSetCallback: 1556c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang { 15573f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1558c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 1559c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1560c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mState == UNINITIALIZED 1561c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang || mState == INITIALIZING 15620e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar || isExecuting()) { 15630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // callback can't be set after codec is executing, 1564c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // or before it's initialized (as the callback 1565c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // will be cleared when it goes to INITIALIZED) 1566c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1567c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1568c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1570c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> callback; 1571c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->findMessage("callback", &callback)); 1572c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1573c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback = callback; 1574c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1575c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 1576c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGI("MediaCodec will operate in async mode"); 1577c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagIsAsync; 1578c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1579c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 1580c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1581c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1582c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 1583c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 1584c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1585c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1586c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatConfigure: 15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15893f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != INITIALIZED) { 1593c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<RefBase> obj; 15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findObject("native-window", &obj)) { 15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber obj.clear(); 16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format; 16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("format", &format)); 16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (obj != NULL) { 16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setObject("native-window", obj); 16071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16087541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber status_t err = setNativeWindow( 16097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber static_cast<NativeWindowWrapper *>(obj.get()) 16107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ->getSurfaceTextureClient()); 16117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 16127541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 1613c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 16147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber break; 16151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 16161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 16177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setNativeWindow(NULL); 16181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 16191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mReplyID = replyID; 16217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setState(CONFIGURING); 16227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 16231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber void *crypto; 16241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (!msg->findPointer("crypto", &crypto)) { 16251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber crypto = NULL; 16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto = static_cast<ICrypto *>(crypto); 16291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16335778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & CONFIGURE_FLAG_ENCODE) { 16345778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", true); 1635e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagIsEncoder; 16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber extractCSD(format); 16398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateConfigureComponent(format); 16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatCreateInputSurface: 16457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 16463f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 16487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // Must be configured, but can't have been started yet. 16507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (mState != CONFIGURED) { 1651c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16527cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 16537cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 16547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 16567cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->initiateCreateInputSurface(); 16577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 16587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 16597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16605778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStart: 16615778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 16623f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16650e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mState == FLUSHED) { 1666d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang setState(STARTED); 16673d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mHavePendingInputBuffers) { 16683d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 16693d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = false; 16703d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 16710e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 16720e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar PostReplyWithError(replyID, OK); 1673d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang break; 16740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else if (mState != CONFIGURED) { 1675c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16795778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 16805778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTING); 16815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16825778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateStart(); 16835778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStop: 1687c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case kWhatRelease: 1688c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 1689aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber State targetState = 1690aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 1691aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 16923f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1693c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 1694c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 169533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 169633223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung && mState != INITIALIZED 16970e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar && mState != CONFIGURED && !isExecuting()) { 169833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 1) Permit release to shut down the component if allocated. 169933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 170033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 2) We may be in "UNINITIALIZED" state already and 170152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan // also shutdown the encoder/decoder without the 170203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // client being aware of this if media server died while 170303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // we were being stopped. The client would assume that 170403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // after stop() returned, it would be safe to call release() 170503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // and it should be in this case, no harm to allow a release() 170603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // if we're already uninitialized. 1707c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response = new AMessage; 17086e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar status_t err = mState == targetState ? OK : INVALID_OPERATION; 17096e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar response->setInt32("err", err); 17106e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (err == OK && targetState == UNINITIALIZED) { 17116e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 17126e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1713c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber response->postReply(replyID); 1714c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 1715c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 1716c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 1717aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 1718aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // It's dead, Jim. Don't expect initiateShutdown to yield 1719aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // any useful results now... 1720aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(UNINITIALIZED); 17216e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (targetState == UNINITIALIZED) { 17226e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 17236e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1724aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (new AMessage)->postReply(replyID); 1725aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber break; 1726aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1727aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1728c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mReplyID = replyID; 1729aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 1730aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1731aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mCodec->initiateShutdown( 1732aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber msg->what() == kWhatStop /* keepComponentAllocated */); 1733c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 17345778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 17355778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17385778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputBuffer: 17395778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 17403f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 17415778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 17425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1743c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1744c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1745c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1746c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1747c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1748c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 17496507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden if (mHaveInputSurface) { 17506507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden ALOGE("dequeueInputBuffer can't be used with input surface"); 1751c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 17526507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden break; 17536507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden } 17546507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueInputBuffer(replyID, true /* new request */)) { 17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 17615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1763c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueInputPending; 17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = replyID; 17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 17721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueInputTimedOut, this); 17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueInputTimeoutGeneration); 17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputTimedOut: 17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueInputTimeoutGeneration) { 17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueInputPending); 17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1792c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, -EAGAIN); 17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatQueueInputBuffer: 18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18013f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1804251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1805c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1807251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1808251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1809251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onQueueInputBuffer(msg); 18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1814c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 18155778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputBuffer: 18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18203f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1823c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1824c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1825c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1826c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1827c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1828c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 18355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1837c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueOutputPending; 18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = replyID; 18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 18461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueOutputTimedOut, this); 18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueOutputTimeoutGeneration); 18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputTimedOut: 18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueOutputTimeoutGeneration) { 18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueOutputPending); 18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1866c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, -EAGAIN); 18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatReleaseOutputBuffer: 18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1878251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1879c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1881251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1882251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1883251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onReleaseOutputBuffer(msg); 18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1888c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 18895778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatSignalEndOfInputStream: 18937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 18943f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 18967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 1897251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1898c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18997cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 1900251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1901251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1902251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 19047cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 19057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 19067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->signalEndOfInputStream(); 19077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 19087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 19097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetBuffers: 19115778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19123f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19135778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 1914e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // Unfortunately widevine legacy source requires knowing all of the 1915e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // codec input buffers, so we have to provide them even in async mode. 1916e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar int32_t widevine = 0; 1917e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->findInt32("widevine", &widevine); 19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1919e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) { 1920c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1922251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1923251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1924251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<sp<ABuffer> > *dstBuffers; 19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber dstBuffers->clear(); 19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < srcBuffers.size(); ++i) { 19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber const BufferInfo &info = srcBuffers.itemAt(i); 19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1939ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber dstBuffers->push_back( 19401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (portIndex == kPortIndexInput && mCrypto != NULL) 1941ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ? info.mEncryptedData : info.mData); 19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(replyID); 19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatFlush: 19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19503f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1953251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1954c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1956251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1957251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1958251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 19620e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // TODO: skip flushing if already FLUSHED 19635778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(FLUSHING); 19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->signalFlush(); 19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1970e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar case kWhatGetInputFormat: 19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetOutputFormat: 19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1973e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> format = 1974e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat); 1975e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 19763f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1979e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((mState != CONFIGURED && mState != STARTING && 19800e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != STARTED && mState != FLUSHING && 19810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != FLUSHED) 1982e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar || format == NULL) { 1983c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1985251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1986251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1987251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19905778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 1991e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar response->setMessage("format", format); 19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1996496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 1997496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 1998496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mCodec->signalRequestIDRFrame(); 1999496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 2000496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 2001496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 2002575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber case kWhatRequestActivityNotification: 2003575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber { 2004575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(mActivityNotify == NULL); 2005575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(msg->findMessage("notify", &mActivityNotify)); 2006575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2007575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 2008575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber break; 2009575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2010575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2011717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo case kWhatGetName: 2012717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo { 20133f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2014717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->senderAwaitsResponse(&replyID)); 2015717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2016717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.empty()) { 2017c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 2018717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2019717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2020717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2021717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response = new AMessage; 2022717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->setString("name", mComponentName.c_str()); 2023717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->postReply(replyID); 2024717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2025717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2026717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2027a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber case kWhatSetParameters: 2028a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber { 20293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2030a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 2031a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2032a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> params; 2033a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->findMessage("params", ¶ms)); 2034a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2035a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber status_t err = onSetParameters(params); 2036a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2037c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 2038a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber break; 2039a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 2040a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 20415778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 20435778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20445778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 20455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20468ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) { 20478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.clear(); 20488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber size_t i = 0; 20508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber for (;;) { 20518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd; 2052a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) { 20538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 20548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.push_back(csd); 20578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ++i; 20588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 2060a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("Found %zu pieces of codec specific data.", mCSD.size()); 20618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 20628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 20648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK(!mCSD.empty()); 20658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo *info = 20677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar &mPortBuffers[kPortIndexInput].itemAt(bufferIndex); 20688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd = *mCSD.begin(); 20708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.erase(mCSD.begin()); 20718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber const sp<ABuffer> &codecInputData = 20738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber (mCrypto != NULL) ? info->mEncryptedData : info->mData; 20748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (csd->size() > codecInputData->capacity()) { 20768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return -EINVAL; 20778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber memcpy(codecInputData->data(), csd->data(), csd->size()); 20808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber AString errorDetailMsg; 20828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20831d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 20848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("index", bufferIndex); 20858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("offset", 0); 20868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("size", csd->size()); 20878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt64("timeUs", 0ll); 20888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 20898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setPointer("errorDetailMsg", &errorDetailMsg); 20908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return onQueueInputBuffer(msg); 20928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 20938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20945778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) { 20957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (newState == INITIALIZED || newState == UNINITIALIZED) { 20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber delete mSoftRenderer; 20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer = NULL; 20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto.clear(); 21007541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setNativeWindow(NULL); 21015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2102671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInputFormat.clear(); 21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat.clear(); 21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagStickyError; 2107e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagIsEncoder; 2108e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 2109c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 2110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 2111575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2112575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2113c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback.clear(); 21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2116717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (newState == UNINITIALIZED) { 2117671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // return any straggling buffers, e.g. if we got here on an error 2118671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar returnBuffersToCodec(); 2119671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 2120aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // The component is gone, mediaserver's probably back up already 2121aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // but should definitely be back up should we try to instantiate 2122aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // another component.. and the cycle continues. 2123aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags &= ~kFlagSawMediaServerDie; 2124717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2125717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber mState = newState; 21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 21292606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 21302606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang updateBatteryStat(); 21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21335778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() { 21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21385778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 21407bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 21435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify != NULL) { 21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> msg = info->mNotify; 21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mOwnedByClient = false; 21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexInput) { 21537fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar /* no error, just returning buffers */ 21547fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar msg->setInt32("err", OK); 21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->post(); 21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].clear(); 21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21635778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers( 21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex, const sp<AMessage> &msg) { 21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2167609b815a3131d22da38b2f452faa9f89daad4039Andy Hung uint32_t bufferID; 2168609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mBufferID == bufferID) { 21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mNotify == NULL); 21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("reply", &info->mNotify)); 21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2179475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mFormat = 2180475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat; 21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].push_back(i); 21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber return i; 21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21925778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset; 21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size; 21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("offset", &offset)); 22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 22025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples; 22044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples; 22054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *key; 22064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *iv; 22074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 22084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // We allow the simpler queueInputBuffer API to be used even in 22104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // secure mode, by fabricating a single unencrypted subSample. 22114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::SubSample ss; 22124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (msg->findSize("size", &size)) { 22144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto != NULL) { 22154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfClearData = size; 22164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfEncryptedData = 0; 22174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples = &ss; 22194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples = 1; 22204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber key = NULL; 22214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber iv = NULL; 22224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } else { 22244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto == NULL) { 22254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber return -EINVAL; 22264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 22294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findSize("numSubSamples", &numSubSamples)); 22304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("key", (void **)&key)); 22314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("iv", (void **)&iv)); 22324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int32_t tmp; 22344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findInt32("mode", &tmp)); 22354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber mode = (CryptoPlugin::Mode)tmp; 22374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size = 0; 22394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber for (size_t i = 0; i < numSubSamples; ++i) { 22404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfClearData; 22414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfEncryptedData; 22424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexInput].size()) { 22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (offset + size > info->mData->capacity()) { 22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> reply = info->mNotify; 22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->setRange(offset, size); 22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt64("timeUs", timeUs); 22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_EOS) { 22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("eos", true); 22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_CODECCONFIG) { 22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("csd", true); 22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mCrypto != NULL) { 22721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (size > info->mEncryptedData->capacity()) { 22731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -ERANGE; 2274ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2275ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 22765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg; 22775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 22785b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 2279fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong ssize_t result = mCrypto->decrypt( 22801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (mFlags & kFlagIsSecure) != 0, 22811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber key, 22821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber iv, 22831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mode, 2284c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info->mSharedEncryptedBuffer, 2285c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker offset, 22864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples, 22874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples, 22885b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mData->base(), 22895b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg); 22901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 2291fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong if (result < 0) { 2292fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong return result; 2293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2294ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2295fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong info->mData->setRange(0, result); 2296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 22987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 22997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 23007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 23027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 23032d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber reply->setBuffer("buffer", info->mData); 23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber reply->post(); 23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23065b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mNotify = NULL; 23075b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23115778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t render; 23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("render", &render)) { 23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber render = 0; 23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23200e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexOutput].size()) { 23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 23357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 23367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 23387bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 23397bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 234079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou if (render && info->mData != NULL && info->mData->size() != 0) { 23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->setInt32("render", true); 23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2343fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar int64_t timestampNs = 0; 2344fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (msg->findInt64("timestampNs", ×tampNs)) { 2345fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar info->mNotify->setInt64("timestampNs", timestampNs); 2346fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } else { 2347fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // TODO: it seems like we should use the timestamp 2348fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // in the (media)buffer as it potentially came from 2349fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // an input surface, but we did not propagate it prior to 2350fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // API 20. Perhaps check for target SDK version. 2351fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0 2352fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 235347aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar ALOGV("using buffer PTS of %" PRId64, timestampNs); 2354fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar timestampNs *= 1000; 2355fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2356fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif 2357fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2358fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mSoftRenderer != NULL) { 23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer->render( 2361475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mData->data(), info->mData->size(), 2362475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu timestampNs, NULL, info->mFormat); 23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->post(); 23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23725778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (availBuffers->empty()) { 23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EAGAIN; 23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index = *availBuffers->begin(); 23825778822d86b0337407514b9372562b86edfa91cdAndreas Huber availBuffers->erase(availBuffers->begin()); 23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(!info->mOwnedByClient); 23867bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 23877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = true; 238903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar 239003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar // set image-data 239103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat != NULL) { 239203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar sp<ABuffer> imageData; 239303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findBuffer("image-data", &imageData)) { 239403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setBuffer("image-data", imageData); 239503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 239603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar int32_t left, top, right, bottom; 239703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) { 239803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setRect("crop-rect", left, top, right, bottom); 239903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 240003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 24017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 24025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24035778822d86b0337407514b9372562b86edfa91cdAndreas Huber return index; 24045778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 24055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow( 24071a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian const sp<Surface> &surfaceTextureClient) { 24087541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber status_t err; 24097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (mNativeWindow != NULL) { 24117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber err = native_window_api_disconnect( 24127541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA); 24137541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 24157541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ALOGW("native_window_api_disconnect returned an error: %s (%d)", 24167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber strerror(-err), err); 24177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow.clear(); 24207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (surfaceTextureClient != NULL) { 24237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber err = native_window_api_connect( 24247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA); 24257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 24277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ALOGE("native_window_api_connect returned an error: %s (%d)", 24287541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber strerror(-err), err); 24297541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24307541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber return err; 24317541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24337541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow = surfaceTextureClient; 24347541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24357541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24367541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber return OK; 24377541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber} 24387541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 2439c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() { 2440c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2441c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) { 2442c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2443c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_INPUT_AVAILABLE); 2444c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2445c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2446c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2447c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2448c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() { 2450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) { 2452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang const sp<ABuffer> &buffer = 2453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mPortBuffers[kPortIndexOutput].itemAt(index).mData; 2454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE); 2456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("offset", buffer->offset()); 2458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("size", buffer->size()); 2459c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int64_t timeUs; 2461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt64("timeUs", timeUs); 2464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t omxFlags; 2466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 2467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2468c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang uint32_t flags = 0; 2469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 2470c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_SYNCFRAME; 2471c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2472c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 2473c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_CODECCONFIG; 2474c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2475c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_EOS) { 2476c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_EOS; 2477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2478c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2479c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("flags", flags); 2480c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2481c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2482c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2483c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2484c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2485749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) { 2486c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2487c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2488c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_ERROR); 2489c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("err", err); 2490749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setInt32("actionCode", actionCode); 2491749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang 2492749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang if (detail != NULL) { 2493749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setString("detail", detail); 2494749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang } 2495c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2498c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2499c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2500c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() { 2501c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2502c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2503c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED); 2504c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("format", mOutputFormat); 2505c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2506c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2507c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2508c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2509c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2510575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() { 2511575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (mActivityNotify == NULL) { 2512575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber return; 2513575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2514575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2515e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang bool isErrorOrOutputChanged = 2516e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang (mFlags & (kFlagStickyError 2517575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber | kFlagOutputBuffersChanged 2518e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang | kFlagOutputFormatChanged)); 2519e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2520e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged 2521575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexInput].empty() 2522575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexOutput].empty()) { 2523e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("input-buffers", 2524e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexInput].size()); 2525e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2526e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged) { 2527e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang // we want consumer to dequeue as many times as it can 2528e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", INT32_MAX); 2529e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } else { 2530e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", 2531e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexOutput].size()); 2532e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } 2533575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify->post(); 2534575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2535575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2536575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 2537575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2538a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 25391d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 2540a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber msg->setMessage("params", params); 2541a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2542a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> response; 2543a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return PostAndAwaitResponse(msg, &response); 2544a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2545a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2546a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 2547a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber mCodec->signalSetParameters(params); 2548a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2549a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return OK; 2550a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2551a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData( 2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const sp<ABuffer> &buffer) { 2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber AString mime; 2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber CHECK(mOutputFormat->findString("mime", &mime)); 2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Codec specific data should be SPS and PPS in a single buffer, 2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // each prefixed by a startcode (0x00 0x00 0x00 0x01). 2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // We separate the two and put them into the output format 2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // under the keys "csd-0" and "csd-1". 2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber unsigned csdIndex = 0; 2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *data = buffer->data(); 2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t size = buffer->size(); 2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *nalStart; 2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t nalSize; 2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber sp<ABuffer> csd = new ABuffer(nalSize + 4); 2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data(), "\x00\x00\x00\x01", 4); 2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data() + 4, nalStart, nalSize); 2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer( 2576a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes AStringPrintf("csd-%u", csdIndex).c_str(), csd); 2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ++csdIndex; 2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (csdIndex != 2) { 2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return ERROR_MALFORMED; 2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // For everything else we just stash the codec specific data into 2586e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the output format as a single piece of csd under "csd-0". 2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer("csd-0", buffer); 2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return OK; 2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} 2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 25932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() { 25942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mState == CONFIGURED && !mBatteryStatNotified) { 25952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier& notifier(BatteryNotifier::getInstance()); 25962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 25972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mIsVideo) { 25982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStartVideo(); 25992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else { 26002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStartAudio(); 26012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 26022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = true; 26042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else if (mState == UNINITIALIZED && mBatteryStatNotified) { 26052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier& notifier(BatteryNotifier::getInstance()); 26062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mIsVideo) { 26082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStopVideo(); 26092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else { 26102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStopAudio(); 26112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 26122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = false; 26142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 26152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 26162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26175778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 2618