MediaCodec.cpp revision 47a2e875bdd2bd25cb8500208940ff1488b01e08
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> 31d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/IOMX.h> 3267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h> 335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h> 355778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h> 365b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h> 37ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h> 385778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h> 397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h> 402606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h> 416f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h> 42e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h> 435778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h> 44744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h> 455778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h> 46d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXClient.h> 47d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/OMXCodec.h> 48d291c222357303b9611cab89d0c3b047584ef377Chong Zhang#include <media/stagefright/PersistentSurface.h> 498b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar#include <media/stagefright/SurfaceUtils.h> 502606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h> 512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h> 522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h> 53e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 545778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android { 555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic inline int getCallingPid() { 5767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return IPCThreadState::self()->getCallingPid(); 5867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 5967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic int64_t getId(sp<IResourceManagerClient> client) { 6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (int64_t) client.get(); 6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) { 6547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu return (err == NO_MEMORY); 6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2; 6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient { 7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {} 7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu virtual bool reclaimResource() { 7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<MediaCodec> codec = mMediaCodec.promote(); 7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (codec == NULL) { 7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // codec is already gone. 7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return true; 7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 7947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu status_t err = codec->reclaim(); 8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerClient failed to release codec with err %d", err); 8267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 8367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (err == OK); 8467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 8567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 868f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu virtual String8 getName() { 878f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu String8 ret; 888f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu sp<MediaCodec> codec = mMediaCodec.promote(); 898f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu if (codec == NULL) { 908f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu // codec is already gone. 918f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu return ret; 928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu 948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu AString name; 958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu if (codec->getName(&name) == OK) { 968f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu ret.setTo(name.c_str()); 978f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 988f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu return ret; 998f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 10067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected: 10267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu virtual ~ResourceManagerClient() {} 10367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate: 10567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu wp<MediaCodec> mMediaCodec; 10667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient); 10867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}; 10967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> { 1112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier(); 112d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang virtual ~BatteryNotifier(); 1132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStartVideo(); 1152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStopVideo(); 1162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStartAudio(); 1172606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStopAudio(); 118d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang void onBatteryStatServiceDied(); 1192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1202606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate: 121d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang struct DeathNotifier : public IBinder::DeathRecipient { 122d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang DeathNotifier() {} 123d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang virtual void binderDied(const wp<IBinder>& /*who*/) { 124d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang BatteryNotifier::getInstance().onBatteryStatServiceDied(); 125d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 126d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang }; 127d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 128d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex mLock; 1292606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang int32_t mVideoRefCount; 1302606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang int32_t mAudioRefCount; 1312606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang sp<IBatteryStats> mBatteryStatService; 132d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<DeathNotifier> mDeathNotifier; 133d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 134d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> getBatteryService_l(); 135d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 136d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier); 1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}; 1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1392606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier) 1402606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1412606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() : 1422606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount(0), 1432606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount(0) { 144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 145d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 146d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() { 147d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mBatteryStatService != NULL) { 148d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return mBatteryStatService; 149d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 150d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // get battery service from service manager 1512606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang const sp<IServiceManager> sm(defaultServiceManager()); 1522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (sm != NULL) { 1532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang const String16 name("batterystats"); 154d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService = 155d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang interface_cast<IBatteryStats>(sm->getService(name)); 1562606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mBatteryStatService == NULL) { 1572606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGE("batterystats service unavailable!"); 158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return NULL; 159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 160d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier = new DeathNotifier(); 16145c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier); 162d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // notify start now if media already started 163d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount > 0) { 164d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService->noteStartVideo(AID_MEDIA); 165d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 166d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount > 0) { 167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService->noteStartAudio(AID_MEDIA); 168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return mBatteryStatService; 171d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 172d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 173d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() { 174d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mDeathNotifier != NULL) { 175d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang IInterface::asBinder(mBatteryStatService)-> 176d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang unlinkToDeath(mDeathNotifier); 1772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() { 181d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 182d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 183d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount == 0 && batteryService != NULL) { 184d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStartVideo(AID_MEDIA); 1852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount++; 1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() { 190d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 1912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mVideoRefCount == 0) { 1922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGW("BatteryNotifier::noteStop(): video refcount is broken!"); 1932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang return; 1942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 196d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 19745c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang 19845c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang mVideoRefCount--; 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 220d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 22145c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang 22245c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang mAudioRefCount--; 223d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount == 0 && batteryService != NULL) { 224d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStopAudio(AID_MEDIA); 2252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 227d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 228d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() { 229d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 230d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService.clear(); 231d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier.clear(); 232d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // Do not reset mVideoRefCount and mAudioRefCount here. The ref 233d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // counting is independent of the battery service availability. 234d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // We need this if battery service becomes available after media 235d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // started. 236d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 237d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() { 23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() { 24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService != NULL) { 24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu IInterface::asBinder(mService)->unlinkToDeath(this); 24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() { 24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IServiceManager> sm = defaultServiceManager(); 24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IBinder> binder = sm->getService(String16("media.resource_manager")); 25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService = interface_cast<IResourceManagerService>(binder); 25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("Failed to get ResourceManagerService"); 25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 25467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 255e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu IInterface::asBinder(mService)->linkToDeath(this); 25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) { 25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerService died."); 26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService.clear(); 26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource( 26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int pid, 26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int64_t clientId, 26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const sp<IResourceManagerClient> client, 26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const Vector<MediaResource> &resources) { 26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService->addResource(pid, clientId, client, resources); 27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) { 27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 28167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService->removeResource(clientId); 28267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 28367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 28467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource( 28567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int callingPid, const Vector<MediaResource> &resources) { 28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 28767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 28867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return false; 28967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 29067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return mService->reclaimResource(callingPid, resources); 29167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 29267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 2945778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType( 295251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) { 2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = new MediaCodec(looper); 2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(mime, true /* nameIsType */, encoder); 299251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 300251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 301251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 302251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 3065778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName( 307251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const sp<ALooper> &looper, const char *name, status_t *err) { 3085778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = new MediaCodec(looper); 3095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */); 311251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 312251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 313251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 314251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 317d291c222357303b9611cab89d0c3b047584ef377Chong Zhang// static 318d291c222357303b9611cab89d0c3b047584ef377Chong Zhangsp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() { 319d291c222357303b9611cab89d0c3b047584ef377Chong Zhang OMXClient client; 320d291c222357303b9611cab89d0c3b047584ef377Chong Zhang CHECK_EQ(client.connect(), (status_t)OK); 321d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<IOMX> omx = client.interface(); 322d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 323d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<IGraphicBufferProducer> bufferProducer; 324d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<IGraphicBufferConsumer> bufferConsumer; 325d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 326d291c222357303b9611cab89d0c3b047584ef377Chong Zhang status_t err = omx->createPersistentInputSurface( 327d291c222357303b9611cab89d0c3b047584ef377Chong Zhang &bufferProducer, &bufferConsumer); 328d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 329d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (err != OK) { 330d291c222357303b9611cab89d0c3b047584ef377Chong Zhang ALOGE("Failed to create persistent input surface."); 331d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return NULL; 332d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 333d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 334d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return new PersistentSurface(bufferProducer, bufferConsumer); 335d291c222357303b9611cab89d0c3b047584ef377Chong Zhang} 336d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 3375778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper) 3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber : mState(UNINITIALIZED), 33947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu mReleasedByResourceManager(false), 3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper(looper), 34192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar mCodec(NULL), 3427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID(0), 3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags(0), 344251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError(OK), 3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer(NULL), 346ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mResourceManagerClient(new ResourceManagerClient(this)), 347ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mResourceManagerService(new ResourceManagerServiceProxy()), 3482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified(false), 3492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mIsVideo(false), 35067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoWidth(0), 35167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoHeight(0), 3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputTimeoutGeneration(0), 3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID(0), 3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputTimeoutGeneration(0), 3556507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mDequeueOutputReplyID(0), 3563d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHaveInputSurface(false), 3573d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers(false) { 3585778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3605778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() { 3615778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, UNINITIALIZED); 36267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 3665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse( 3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &msg, sp<AMessage> *response) { 3685778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = msg->postAndAwaitResponse(response); 3695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3705778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!(*response)->findInt32("err", &err)) { 3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = OK; 3765778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3785778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3795778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3813f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) { 38247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu int32_t finalErr = err; 38347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu if (mReleasedByResourceManager) { 38447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu // override the err code if MediaCodec has been released by ResourceManager. 38547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu finalErr = DEAD_OBJECT; 38647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu } 38747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 388c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 38947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu response->setInt32("err", finalErr); 390c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 391c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 392c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 393dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) { 39467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->init(); 39567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 396671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // save init parameters for reset 397671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitName = name; 398671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitNameIsType = nameIsType; 399671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitIsEncoder = encoder; 400671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 4015778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Current video decoders do not return from OMX_FillThisBuffer 4025778822d86b0337407514b9372562b86edfa91cdAndreas Huber // quickly, violating the OpenMAX specs, until that is remedied 4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber // we need to invest in an extra looper to free the main event 4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber // queue. 405744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 406bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) { 407744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mCodec = new ACodec; 408744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else if (!nameIsType 409bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung && !strncasecmp(name.c_str(), "android.filter.", 15)) { 410744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mCodec = new MediaFilter; 411744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else { 412744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return NAME_NOT_FOUND; 413744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 414744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 41567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu bool secureCodec = false; 416dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) { 41767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 4186f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } else { 4196f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen AString tmp = name; 4206f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (tmp.endsWith(".secure")) { 42167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu secureCodec = true; 4226f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen tmp.erase(tmp.size() - 7, 7); 4236f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 42460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); 42548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung if (mcl == NULL) { 42648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung mCodec = NULL; // remove the codec. 42748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung return NO_INIT; // if called from Java should raise IOException 42848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung } 4296f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); 4306f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (codecIdx >= 0) { 43160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); 43260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<AString> mimes; 43360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar info->getSupportedMimes(&mimes); 43460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t i = 0; i < mimes.size(); i++) { 43560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (mimes[i].startsWith("video/")) { 43667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 43760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar break; 4386f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4396f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4406f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 44467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // video codec needs dedicated looper 4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mCodecLooper == NULL) { 4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper = new ALooper; 4475778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->setName("CodecLooper"); 4485778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 4495778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4515778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->registerHandler(mCodec); 4525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 4535778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(mCodec); 4545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(this); 4575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this)); 4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatInit, this); 4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setString("name", name); 4625778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("nameIsType", nameIsType); 4635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4645778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 4655778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("encoder", encoder); 4665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 46867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 46967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 47067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec; 471c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec; 472c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(String8(type), String8(subtype), 1)); 47367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 47467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 47567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 47667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 47767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 47867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 47967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 48067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 48167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 48267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 48367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 48467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 48567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 48667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 48767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 4885778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 490c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) { 4911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetCallback, this); 492c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("callback", callback); 493c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 494c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response; 495c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang return PostAndAwaitResponse(msg, &response); 496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 4985778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure( 4995778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &format, 500f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar const sp<Surface> &surface, 5011bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const sp<ICrypto> &crypto, 5025778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags) { 5031d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigure, this); 5045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("width", &mVideoWidth); 50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("height", &mVideoHeight); 50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 50967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 5105778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setMessage("format", format); 5115778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 512f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar msg->setObject("surface", surface); 5131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 5141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (crypto != NULL) { 5151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber msg->setPointer("crypto", crypto.get()); 5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 51867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // save msg for reset 51967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mConfigureMsg = msg; 520f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 52167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 52367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = (mFlags & kFlagIsSecure) ? 52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu kResourceSecureCodec : kResourceNonSecureCodec; 525c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec; 526c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(String8(type), String8(subtype), 1)); 52767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 52867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 52967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1)); 53067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 53167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 53267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 53367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 53467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 53567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 53667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 537f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 53867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 53967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 54067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK && err != INVALID_OPERATION) { 54167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // MediaCodec now set state to UNINITIALIZED upon any fatal error. 54267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // To maintain backward-compatibility, do a reset() to put codec 54367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // back into INITIALIZED state. 54467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // But don't reset if the err is INVALID_OPERATION, which means 54567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the configure failure is due to wrong state. 54667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 54767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("configure failed with err 0x%08x, resetting...", err); 54867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu reset(); 54967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 55167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 553f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang } 554f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang return err; 5555778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 557d291c222357303b9611cab89d0c3b047584ef377Chong Zhangstatus_t MediaCodec::usePersistentInputSurface( 558d291c222357303b9611cab89d0c3b047584ef377Chong Zhang const sp<PersistentSurface> &surface) { 559d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<AMessage> msg = new AMessage(kWhatUsePersistentInputSurface, this); 560d291c222357303b9611cab89d0c3b047584ef377Chong Zhang msg->setObject("input-surface", surface.get()); 561d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 562d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<AMessage> response; 563d291c222357303b9611cab89d0c3b047584ef377Chong Zhang return PostAndAwaitResponse(msg, &response); 564d291c222357303b9611cab89d0c3b047584ef377Chong Zhang} 565d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 5661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::setSurface(const sp<Surface> &surface) { 5671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> msg = new AMessage(kWhatSetSurface, this); 5681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar msg->setObject("surface", surface); 5691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 5701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> response; 5711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return PostAndAwaitResponse(msg, &response); 5721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 5731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 5747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface( 5757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 5761d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this); 5777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 5787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 5797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = PostAndAwaitResponse(msg, &response); 5807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (err == NO_ERROR) { 5817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // unwrap the sp<IGraphicBufferProducer> 5827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 5837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden bool found = response->findObject("input-surface", &obj); 5847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(found); 5857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<BufferProducerWrapper> wrapper( 5867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden static_cast<BufferProducerWrapper*>(obj.get())); 5877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden *bufferProducer = wrapper->getBufferProducer(); 5887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 5897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGW("createInputSurface failed, err=%d", err); 5907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 5917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return err; 5927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 5937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() { 59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mIsVideo) { 59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return 0; 59767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 59967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu uint64_t size = 0; 60067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]); 60167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (size_t i = 0; i < portNum; ++i) { 60267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // TODO: this is just an estimation, we should get the real buffer size from ACodec. 60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2; 60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return size; 60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 60767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 608c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wuvoid MediaCodec::addResource(const String8 &type, const String8 &subtype, uint64_t value) { 60967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 610c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(type, subtype, value)); 61167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->addResource( 61267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources); 61367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 61467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6155778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() { 6161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, this); 6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 61867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 61967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 62067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = (mFlags & kFlagIsSecure) ? 62167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu kResourceSecureCodec : kResourceNonSecureCodec; 622c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec; 623c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(String8(type), String8(subtype), 1)); 62467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 62567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 62667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1)); 62767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 62867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 62967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 63067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 63167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 63267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 63367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Recover codec from previous error before retry start. 63467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = reset(); 63567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 63667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to reset codec"); 63767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 63867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 63967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 64067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(mConfigureMsg, &response); 64167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 64267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to configure codec"); 64367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 64467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 64567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 64667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 64767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 64867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 64967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 65067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 65167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 65267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 65367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 6545778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6565778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() { 6571d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, this); 6585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6595778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 66347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wustatus_t MediaCodec::reclaim() { 66447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu sp<AMessage> msg = new AMessage(kWhatRelease, this); 66547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu msg->setInt32("reclaimed", 1); 66647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 66747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu sp<AMessage> response; 66847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu return PostAndAwaitResponse(msg, &response); 66947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu} 67047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 671c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() { 6721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRelease, this); 673c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 674c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response; 675c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return PostAndAwaitResponse(msg, &response); 676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 678671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() { 679671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar /* When external-facing MediaCodec object is created, 680671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar it is already initialized. Thus, reset is essentially 681671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar release() followed by init(), plus clearing the state */ 682671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 683671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar status_t err = release(); 684671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 685671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // unregister handlers 686671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodec != NULL) { 687671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodecLooper != NULL) { 688671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodecLooper->unregisterHandler(mCodec->id()); 689671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } else { 690671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(mCodec->id()); 691671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 692671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodec = NULL; 693671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 694671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(id()); 695671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 696671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mFlags = 0; // clear all flags 697251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 698671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 699671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // reset state not reset by setState(UNINITIALIZED) 700671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mReplyID = 0; 701671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputReplyID = 0; 702671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputReplyID = 0; 703671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputTimeoutGeneration = 0; 704671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputTimeoutGeneration = 0; 705671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mHaveInputSurface = false; 706671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 707671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (err == OK) { 708dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung err = init(mInitName, mInitNameIsType, mInitIsEncoder); 709671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 710671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar return err; 711671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar} 712671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 7135778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer( 7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index, 7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset, 7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size, 7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t presentationTimeUs, 7185b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 7195b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 7205b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 7215b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 7225b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 7235b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7241d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("offset", offset); 7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("size", size); 7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 7305b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer( 7374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t index, 7384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t offset, 7394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples, 7404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples, 7414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t key[16], 7424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t iv[16], 7434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode, 7444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int64_t presentationTimeUs, 7455b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 7465b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 7475b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 7485b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 7495b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 7505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7511d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 7524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("index", index); 7534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("offset", offset); 7544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("subSamples", (void *)subSamples); 7554b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("numSubSamples", numSubSamples); 7564b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("key", (void *)key); 7574b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("iv", (void *)iv); 7584b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("mode", mode); 7594b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 7604b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("flags", flags); 7615b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 7624b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7634b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber sp<AMessage> response; 7645b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber status_t err = PostAndAwaitResponse(msg, &response); 7655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7665b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber return err; 7674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber} 7684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7695778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 7701d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this); 7715778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7735778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7745778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7755778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7765778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7795778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7845778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer( 7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *index, 7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *offset, 7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *size, 7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t *presentationTimeUs, 7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t *flags, 7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs) { 7911d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this); 7925778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7945778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("offset", offset)); 8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("size", size)); 8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt64("timeUs", presentationTimeUs)); 8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt32("flags", (int32_t *)flags)); 8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 8075778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8095778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 8101d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 8115778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 8125778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("render", true); 8135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8145778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8155778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8165778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 818fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) { 8191d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 820fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setSize("index", index); 821fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt32("render", true); 822fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt64("timestampNs", timestampNs); 823fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 824fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar sp<AMessage> response; 825fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar return PostAndAwaitResponse(msg, &response); 826fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar} 827fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 8285778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) { 8291d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 8305778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 8315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() { 8371d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this); 8387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 8397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 8407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return PostAndAwaitResponse(msg, &response); 8417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 8427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 8435778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 8441d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this); 8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findMessage("format", format)); 8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8545778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 8555778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 857e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const { 8581d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this); 859e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 860e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> response; 861e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar status_t err; 862e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 863e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return err; 864e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 865e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 866e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(response->findMessage("format", format)); 867e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 868e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return OK; 869e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar} 870e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 871717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const { 8721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetName, this); 873717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 874717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response; 875717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo status_t err; 876717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 877717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return err; 878717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 879717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 880717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(response->findString("name", name)); 881717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 882717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return OK; 883717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo} 884717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 885e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const { 886e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 887e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("portIndex", kPortIndexInput); 888e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setPointer("buffers", buffers); 889e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("widevine", true); 890e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 891e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> response; 892e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar return PostAndAwaitResponse(msg, &response); 893e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar} 894e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 8955778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 8961d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8975778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexInput); 8985778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 9051d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 9065778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexOutput); 9075778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 9085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9095778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 9105778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 9115778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9137bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) { 9147bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 9157bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, buffer, &format); 9167bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9177bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9187bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) { 9197bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> buffer; 9207bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, &buffer, format); 9217bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9227bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) { 9247bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 9257bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexInput, index, buffer, &format); 9267bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9277bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9280e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const { 9290e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar return mState == STARTED || mState == FLUSHED; 9300e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar} 9310e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar 9327bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat( 9337bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar size_t portIndex, size_t index, 9347bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> *buffer, sp<AMessage> *format) { 9357bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // use mutex instead of a context switch 9367bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 93747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu if (mReleasedByResourceManager) { 93847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu return DEAD_OBJECT; 93947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu } 94047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 9417bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar buffer->clear(); 9427bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar format->clear(); 9430e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 9447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return INVALID_OPERATION; 9457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 9467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we do not want mPortBuffers to change during this section 9487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we also don't want mOwnedByClient to change during this 9497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 9507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 9517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar if (index < buffers->size()) { 9527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo &info = buffers->itemAt(index); 9537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar if (info.mOwnedByClient) { 9540837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar // by the time buffers array is initialized, crypto is set 9550837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar if (portIndex == kPortIndexInput && mCrypto != NULL) { 9560837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar *buffer = info.mEncryptedData; 9570837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar } else { 9580837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar *buffer = info.mData; 9590837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar } 9607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar *format = info.mFormat; 9617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 9627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 9637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return OK; 9647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9665778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() { 9671d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFlush, this); 9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 973496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() { 9741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatRequestIDRFrame, this))->post(); 975496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 976496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber return OK; 977496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 978496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 979575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 9801d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this); 981575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->setMessage("notify", notify); 982575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->post(); 983575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 984575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber//////////////////////////////////////////////////////////////////////////////// 9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9875778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() { 9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueInputPending) { 989c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION); 9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueOutputPending) { 997c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION); 9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10053f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 10060e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueInputPending))) { 1008c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 1010251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1011251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1012251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return true; 10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 10300e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 10315778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 103247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu PostReplyWithError(replyID, INVALID_OPERATION); 1033251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 103447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu PostReplyWithError(replyID, getStickyError()); 10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputBuffersChanged) { 103647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu PostReplyWithError(replyID, INFO_OUTPUT_BUFFERS_CHANGED); 10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputFormatChanged) { 103947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu PostReplyWithError(replyID, INFO_FORMAT_CHANGED); 10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 104247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu sp<AMessage> response = new AMessage; 10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexOutput); 10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 10485778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<ABuffer> &buffer = 10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[kPortIndexOutput].itemAt(index).mData; 10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("offset", buffer->offset()); 10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("size", buffer->size()); 10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt64("timeUs", timeUs); 10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags = 0; 10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_SYNCFRAME; 10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 10705778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_CODECCONFIG; 10715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_EOS) { 10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_EOS; 10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10765778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("flags", flags); 107747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu response->postReply(replyID); 10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 10815778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (msg->what()) { 10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatCodecNotify: 10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10875778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t what; 10885778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("what", &what)); 10895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10905778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (what) { 109192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatError: 10925778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1093251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung int32_t err, actionCode; 1094251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("err", &err)); 1095251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("actionCode", &actionCode)); 10965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10979e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen ALOGE("Codec reported err %#x, actionCode %d, while in state %d", 10989e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen err, actionCode, mState); 1099251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err == DEAD_OBJECT) { 1100aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags |= kFlagSawMediaServerDie; 110152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 1102aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1103aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 11045530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia bool sendErrorResponse = true; 11055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11065778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (mState) { 11075778822d86b0337407514b9372562b86edfa91cdAndreas Huber case INITIALIZING: 11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(UNINITIALIZED); 11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber case CONFIGURING: 11145778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1115c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1116c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : INITIALIZED); 11175778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTING: 11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1122c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1123c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : CONFIGURED); 11245778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11275778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STOPPING: 1128c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case RELEASING: 11295778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11305778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Ignore the error, assuming we'll still get 11315778822d86b0337407514b9372562b86edfa91cdAndreas Huber // the shutdown complete notification. 11325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11335530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 113403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 1135aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 113603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // MediaServer died, there definitely won't 113703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // be a shutdown complete notification after 113803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // all. 113903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 114003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // note that we're directly going from 114103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // STOPPING->UNINITIALIZED, instead of the 114203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // usual STOPPING->INITIALIZED state. 114303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber setState(UNINITIALIZED); 11446e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (mState == RELEASING) { 11456e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 11466e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 114703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber (new AMessage)->postReply(mReplyID); 114803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber } 11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11505778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber case FLUSHING: 11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11549e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen if (actionCode == ACTION_CODE_FATAL) { 11559e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState(UNINITIALIZED); 11569e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } else { 11579e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState( 11589e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen (mFlags & kFlagIsAsync) ? FLUSHED : STARTED); 11599e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } 11605778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar case FLUSHED: 11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTED: 11655778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11665530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1168251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1169575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11715778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 1172c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1173c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1174251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1175251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1176251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1177251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1178251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1179251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1180251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1181251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1182251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1183251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1184251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1185c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11895778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 11905778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11915530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1193251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1194575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1195c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1196251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung // actionCode in an uninitialized state is always fatal. 1197251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (mState == UNINITIALIZED) { 1198251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung actionCode = ACTION_CODE_FATAL; 1199251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1200c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1201251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1202251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1203251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1204251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1205251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1206251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1207251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1208251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1209251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1210251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1211251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1212c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 12135778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12145778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12175530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (sendErrorResponse) { 1218251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(mReplyID, err); 12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 122392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentAllocated: 12245778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 12255778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, INITIALIZING); 12265778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZED); 122752dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags |= kFlagIsComponentAllocated; 12285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1229717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->findString("componentName", &mComponentName)); 12305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1231717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.startsWith("OMX.google.")) { 12323a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 12335778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 12343a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags &= ~kFlagUsesSoftwareRenderer; 12355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 123767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu String8 resourceType; 1238717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.endsWith(".secure")) { 12391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags |= kFlagIsSecure; 124067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resourceType = String8(kResourceSecureCodec); 12411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 12421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags &= ~kFlagIsSecure; 124367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resourceType = String8(kResourceNonSecureCodec); 12441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1245c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu 1246c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec; 1247c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu addResource(resourceType, String8(subtype), 1); 12481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 125392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentConfigured: 12545778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, CONFIGURING); 12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12576507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden // reset input surface flag 12586507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = false; 12596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 1260e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("input-format", &mInputFormat)); 1261e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("output-format", &mOutputFormat)); 1262e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 12633a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar int32_t usingSwRenderer; 12643a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer) 12653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar && usingSwRenderer) { 12663a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 12673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 12682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang setState(CONFIGURED); 12695778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 12705778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 127392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatInputSurfaceCreated: 12747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 127592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to initiateCreateInputSurface() 12767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = NO_ERROR; 12771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> response = new AMessage; 12787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (!msg->findInt32("err", &err)) { 12797cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 12807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden msg->findObject("input-surface", &obj); 12817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(obj != NULL); 12827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setObject("input-surface", obj); 12836507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = true; 12847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 12857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 12867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 12887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 12897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 1291d291c222357303b9611cab89d0c3b047584ef377Chong Zhang case CodecBase::kWhatInputSurfaceAccepted: 1292d291c222357303b9611cab89d0c3b047584ef377Chong Zhang { 1293d291c222357303b9611cab89d0c3b047584ef377Chong Zhang // response to initiateUsePersistentInputSurface() 1294d291c222357303b9611cab89d0c3b047584ef377Chong Zhang status_t err = NO_ERROR; 1295d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<AMessage> response = new AMessage(); 1296d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (!msg->findInt32("err", &err)) { 1297d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mHaveInputSurface = true; 1298d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 1299d291c222357303b9611cab89d0c3b047584ef377Chong Zhang response->setInt32("err", err); 1300d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 1301d291c222357303b9611cab89d0c3b047584ef377Chong Zhang response->postReply(mReplyID); 1302d291c222357303b9611cab89d0c3b047584ef377Chong Zhang break; 1303d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 1304d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 130592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatSignaledInputEOS: 13067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 130792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to signalEndOfInputStream() 13081dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AMessage> response = new AMessage; 13097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err; 13107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (msg->findInt32("err", &err)) { 13117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 13127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 13137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 13147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 13157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 13167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 13177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 131892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatBuffersAllocated: 13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13207bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("%s buffers allocated", 13255778822d86b0337407514b9372562b86edfa91cdAndreas Huber portIndex == kPortIndexInput ? "input" : "output"); 13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput 13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber || portIndex == kPortIndexOutput); 13295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13305778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[portIndex].clear(); 13315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1334eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber sp<RefBase> obj; 1335eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber CHECK(msg->findObject("portDesc", &obj)); 1336eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 133792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar sp<CodecBase::PortDescription> portDesc = 133892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar static_cast<CodecBase::PortDescription *>(obj.get()); 13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1340eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber size_t numBuffers = portDesc->countBuffers(); 13415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1342c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker size_t totalSize = 0; 1343c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker for (size_t i = 0; i < numBuffers; ++i) { 1344c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (portIndex == kPortIndexInput && mCrypto != NULL) { 1345c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker totalSize += portDesc->bufferAt(i)->capacity(); 1346c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1347c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1348c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1349c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (totalSize) { 1350c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker mDealer = new MemoryDealer(totalSize, "MediaCodec"); 1351c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1352c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1353eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber for (size_t i = 0; i < numBuffers; ++i) { 13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo info; 1355eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mBufferID = portDesc->bufferIDAt(i); 13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber info.mOwnedByClient = false; 1357eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mData = portDesc->bufferAt(i); 13585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (portIndex == kPortIndexInput && mCrypto != NULL) { 1360c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sp<IMemory> mem = mDealer->allocate(info.mData->capacity()); 1361ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info.mEncryptedData = 1362c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker new ABuffer(mem->pointer(), info.mData->capacity()); 1363c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info.mSharedEncryptedBuffer = mem; 1364ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 1365ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffers->push_back(info); 13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexOutput) { 13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState == STARTING) { 13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We're always allocating output buffers after 13725778822d86b0337407514b9372562b86edfa91cdAndreas Huber // allocating input buffers, so this is a good 13735778822d86b0337407514b9372562b86edfa91cdAndreas Huber // indication that now all buffers are allocated. 137467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 1375c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu String8 subtype; 1376c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu addResource( 1377c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu String8(kResourceGraphicMemory), 1378c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu subtype, 1379c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu getGraphicBufferSize()); 138067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 13815778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTED); 13825778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 13835778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 13845778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagOutputBuffersChanged; 1385575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 13865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13875778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13885778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13895778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 139192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatOutputFormatChanged: 13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("codec output format changed"); 13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1395475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mSoftRenderer == NULL && 1396f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar mSurface != NULL && 13973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar (mFlags & kFlagUsesSoftwareRenderer)) { 13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString mime; 13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("mime", &mime)); 14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1401475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mime.startsWithIgnoreCase("video/")) { 1402f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar mSoftRenderer = new SoftwareRenderer(mSurface); 14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14065778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat = msg; 1407e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1408e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagIsEncoder) { 1409e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Before we announce the format change we should 1410e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // collect codec specific data and amend the output 1411e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format as necessary. 1412e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagGatherCodecSpecificData; 1413c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagIsAsync) { 1414c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1415e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 1416e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagOutputFormatChanged; 1417e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber postActivityNotificationIfPossible(); 1418e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 14192514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 14202514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker // Notify mCrypto of video resolution changes 14212514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker if (mCrypto != NULL) { 14228140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar int32_t left, top, right, bottom, width, height; 14238140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { 14248140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(right - left + 1, bottom - top + 1); 14258140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } else if (mOutputFormat->findInt32("width", &width) 14268140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar && mOutputFormat->findInt32("height", &height)) { 14278140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(width, height); 14288140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } 14292514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 14302514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 143492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFillThisBuffer: 14355778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexInput, msg); 14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1438c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1439c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1440c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 14425778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14435778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (!mCSD.empty()) { 14468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 14478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK_GE(index, 0); 14488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 14498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // If codec specific data had been specified as 14508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // part of the format in the call to configure and 14518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // if there's more csd left, we submit it here 14528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // clients only get access to input buffers once 14538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // this data has been exhausted. 14548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 14558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber status_t err = queueCSDInputBuffer(index); 14568ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 14578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (err != OK) { 14588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ALOGE("queueCSDInputBuffer failed w/ error %d", 14598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber err); 14608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1461251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1462575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1463575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 14648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber cancelPendingDequeueOperations(); 14658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 14668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 14678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 14688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 14706e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (!mHaveInputSurface) { 14713d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mState == FLUSHED) { 14723d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = true; 14733d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } else { 14743d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 14753d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 14766e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueInputPending) { 14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 1483575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1484575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14875778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 148992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatDrainThisBuffer: 14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14915778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexOutput, msg); 14925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1494c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 14965778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15002d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 15012d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", &omxFlags)); 15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("omxFlags", omxFlags); 15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1508e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagGatherCodecSpecificData) { 1509e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // This is the very first output buffer after a 1510e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format change was signalled, it'll either contain 1511e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the one piece of codec specific data we can expect 1512e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // or there won't be codec specific data. 1513e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 1514e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber status_t err = 1515e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber amendOutputFormatWithCodecSpecificData(buffer); 1516e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1517e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (err != OK) { 1518e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ALOGE("Codec spit out malformed codec " 1519e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber "specific data!"); 1520e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1521e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1522e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1523e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 1524c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1525c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1526c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1527c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagOutputFormatChanged; 1528c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1529e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1530e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1531c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1532c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputBufferAvailable(); 1533c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueOutputPending) { 15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 1539575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1540575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1542575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 154692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatEOS: 15475778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15485778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We already notify the client of this by using the 15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber // corresponding flag in "onOutputBufferReady". 15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 155392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatShutdownCompleted: 15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1555c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == STOPPING) { 1556c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(INITIALIZED); 1557c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } else { 1558c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK_EQ(mState, RELEASING); 1559c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(UNINITIALIZED); 15606e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 1561c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 156252dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 156467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 156567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 15665778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 15675778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 157092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFlushCompleted: 15715778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15725530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (mState != FLUSHING) { 15735530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia ALOGW("received FlushCompleted message in state %d", 15745530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia mState); 15755530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia break; 15765530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia } 15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15780e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mFlags & kFlagIsAsync) { 15790e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(FLUSHED); 15800e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else { 15810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(STARTED); 15820e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 15830e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } 15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatInit: 15965778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15973f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 15995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != UNINITIALIZED) { 1601c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZING); 16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString name; 16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("name", &name)); 16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t nameIsType; 16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t encoder = false; 16130db280176bd3277e3256252d063f3712b1905ba9Andreas Huber CHECK(msg->findInt32("nameIsType", &nameIsType)); 16140db280176bd3277e3256252d063f3712b1905ba9Andreas Huber if (nameIsType) { 16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("encoder", &encoder)); 16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16185778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format = new AMessage; 16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("mime", name.c_str()); 16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", encoder); 16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 16245778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("componentName", name.c_str()); 16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16275778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateAllocateComponent(format); 16285778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1631c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang case kWhatSetCallback: 1632c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang { 16333f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 1635c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1636c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mState == UNINITIALIZED 1637c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang || mState == INITIALIZING 16380e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar || isExecuting()) { 16390e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // callback can't be set after codec is executing, 1640c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // or before it's initialized (as the callback 1641c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // will be cleared when it goes to INITIALIZED) 1642c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1643c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1644c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1645c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1646c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> callback; 1647c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->findMessage("callback", &callback)); 1648c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1649c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback = callback; 1650c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1651c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 1652c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGI("MediaCodec will operate in async mode"); 1653c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagIsAsync; 1654c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1655c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 1656c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1657c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1658c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 1659c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 1660c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1661c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1662c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 16635778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatConfigure: 16645778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 16653f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != INITIALIZED) { 1669c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<RefBase> obj; 1674f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar CHECK(msg->findObject("surface", &obj)); 16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16765778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format; 16775778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("format", &format)); 16785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16798b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar int32_t push; 16808b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar if (msg->findInt32("push-blank-buffers-on-shutdown", &push) && push != 0) { 16818b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar mFlags |= kFlagPushBlankBuffersOnShutdown; 16828b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar } 16838b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar 16845778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (obj != NULL) { 16855778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setObject("native-window", obj); 1686f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar status_t err = handleSetSurface(static_cast<Surface *>(obj.get())); 16877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 1688c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 16897541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber break; 16901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 16911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 1692f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar handleSetSurface(NULL); 16931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 16941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mReplyID = replyID; 16967541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setState(CONFIGURING); 16977541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 16981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber void *crypto; 16991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (!msg->findPointer("crypto", &crypto)) { 17001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber crypto = NULL; 17015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto = static_cast<ICrypto *>(crypto); 17041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 17055778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 17065778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 17075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17085778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & CONFIGURE_FLAG_ENCODE) { 17095778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", true); 1710e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagIsEncoder; 17115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber extractCSD(format); 17148ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 17155778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateConfigureComponent(format); 17165778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17191dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case kWhatSetSurface: 17201dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar { 17211dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<AReplyToken> replyID; 17221dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar CHECK(msg->senderAwaitsResponse(&replyID)); 17231dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 17241dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = OK; 17251dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<Surface> surface; 17261dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 17271dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar switch (mState) { 17281dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case CONFIGURED: 17291dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case STARTED: 17301dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar case FLUSHED: 17311dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar { 17321dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<RefBase> obj; 17331dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar (void)msg->findObject("surface", &obj); 17341dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar sp<Surface> surface = static_cast<Surface *>(obj.get()); 17351dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mSurface == NULL) { 17361dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // do not support setting surface if it was not set 17371dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = INVALID_OPERATION; 17381dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else if (obj == NULL) { 17391dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // do not support unsetting surface 17401dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = BAD_VALUE; 17411dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else { 17421dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = connectToSurface(surface); 17431dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == BAD_VALUE) { 17441dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // assuming reconnecting to same surface 17451dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // TODO: check if it is the same surface 17461dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = OK; 17471dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else { 17481dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == OK) { 17491dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mFlags & kFlagUsesSoftwareRenderer) { 17508b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar if (mSoftRenderer != NULL 17518b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar && (mFlags & kFlagPushBlankBuffersOnShutdown)) { 17528b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar pushBlankBuffersToNativeWindow(mSurface.get()); 17538b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar } 17541dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mSoftRenderer = new SoftwareRenderer(surface); 17551dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // TODO: check if this was successful 17561dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else { 17571dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = mCodec->setSurface(surface); 17581dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 17591dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 17601dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == OK) { 17611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar (void)disconnectFromSurface(); 17621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mSurface = surface; 17631dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 17641dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 17651dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 17661dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar break; 17671dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 17681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 17691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar default: 17701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = INVALID_OPERATION; 17711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar break; 17721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 17731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 17741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar PostReplyWithError(replyID, err); 17751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar break; 17761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 17771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar 17787cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatCreateInputSurface: 1779d291c222357303b9611cab89d0c3b047584ef377Chong Zhang case kWhatUsePersistentInputSurface: 17807cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 17813f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 17827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 17837cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 17847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // Must be configured, but can't have been started yet. 17857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (mState != CONFIGURED) { 1786c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 17877cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 17887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 17897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 17907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 1791d291c222357303b9611cab89d0c3b047584ef377Chong Zhang if (msg->what() == kWhatCreateInputSurface) { 1792d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mCodec->initiateCreateInputSurface(); 1793d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } else { 1794d291c222357303b9611cab89d0c3b047584ef377Chong Zhang sp<RefBase> obj; 1795d291c222357303b9611cab89d0c3b047584ef377Chong Zhang CHECK(msg->findObject("input-surface", &obj)); 1796d291c222357303b9611cab89d0c3b047584ef377Chong Zhang 1797d291c222357303b9611cab89d0c3b047584ef377Chong Zhang mCodec->initiateUsePersistentInputSurface( 1798d291c222357303b9611cab89d0c3b047584ef377Chong Zhang static_cast<PersistentSurface *>(obj.get())); 1799d291c222357303b9611cab89d0c3b047584ef377Chong Zhang } 18007cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 18017cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStart: 18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18043f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mState == FLUSHED) { 1808d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang setState(STARTED); 18093d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mHavePendingInputBuffers) { 18103d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 18113d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = false; 18123d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 18130e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 18140e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar PostReplyWithError(replyID, OK); 1815d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang break; 18160e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else if (mState != CONFIGURED) { 1817c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTING); 18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateStart(); 18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStop: 1829c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case kWhatRelease: 1830c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 1831aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber State targetState = 1832aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 1833aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 18343f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1835c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 1836c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 183747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu // already stopped/released 183847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu if (mState == UNINITIALIZED && mReleasedByResourceManager) { 183947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu sp<AMessage> response = new AMessage; 184047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu response->setInt32("err", OK); 184147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu response->postReply(replyID); 184247a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu break; 184347a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu } 184447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 184547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu int32_t reclaimed = 0; 184647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu msg->findInt32("reclaimed", &reclaimed); 184747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu if (reclaimed) { 184847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu mReleasedByResourceManager = true; 184947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu } 185047a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu 185133223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 185233223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung && mState != INITIALIZED 18530e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar && mState != CONFIGURED && !isExecuting()) { 185433223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 1) Permit release to shut down the component if allocated. 185533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 185633223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 2) We may be in "UNINITIALIZED" state already and 185752dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan // also shutdown the encoder/decoder without the 185803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // client being aware of this if media server died while 185903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // we were being stopped. The client would assume that 186003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // after stop() returned, it would be safe to call release() 186103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // and it should be in this case, no harm to allow a release() 186203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // if we're already uninitialized. 1863c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response = new AMessage; 186447a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu // TODO: we shouldn't throw an exception for stop/release. Change this to wait until 186547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu // the previous stop/release completes and then reply with OK. 18666e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar status_t err = mState == targetState ? OK : INVALID_OPERATION; 18676e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar response->setInt32("err", err); 18686e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (err == OK && targetState == UNINITIALIZED) { 18696e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 18706e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1871c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber response->postReply(replyID); 1872c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 1873c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 1874c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 1875aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 1876aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // It's dead, Jim. Don't expect initiateShutdown to yield 1877aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // any useful results now... 1878aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(UNINITIALIZED); 18796e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (targetState == UNINITIALIZED) { 18806e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 18816e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1882aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (new AMessage)->postReply(replyID); 1883aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber break; 1884aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1885aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1886c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mReplyID = replyID; 1887aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 1888aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1889aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mCodec->initiateShutdown( 1890aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber msg->what() == kWhatStop /* keepComponentAllocated */); 1891c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 18925778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 18938b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar 18948b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar if (mSoftRenderer != NULL && (mFlags & kFlagPushBlankBuffersOnShutdown)) { 18958b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar pushBlankBuffersToNativeWindow(mSurface.get()); 18968b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar } 18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputBuffer: 19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1905c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1906c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1907c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1908c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1909c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1910c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 19116507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden if (mHaveInputSurface) { 19126507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden ALOGE("dequeueInputBuffer can't be used with input surface"); 1913c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden break; 19156507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden } 19166507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueInputBuffer(replyID, true /* new request */)) { 19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1925c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19295778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueInputPending; 19305778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = replyID; 19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 19341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueInputTimedOut, this); 19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueInputTimeoutGeneration); 19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputTimedOut: 19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueInputTimeoutGeneration) { 19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueInputPending); 19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1954c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, -EAGAIN); 19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatQueueInputBuffer: 19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19633f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19645778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1966251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1967c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19685778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1969251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1970251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1971251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19725778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onQueueInputBuffer(msg); 19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1976c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19805778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputBuffer: 19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19823f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1985c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1986c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1987c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1988c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1989c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1990c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 19915778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 19925778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19935778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19955778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 19965778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 19975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1999c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueOutputPending; 20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = replyID; 20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20065778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 20075778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 20081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueOutputTimedOut, this); 20095778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 20105778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueOutputTimeoutGeneration); 20115778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 20125778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20135778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20145778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20165778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputTimedOut: 20175778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 20185778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 20195778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 20205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20215778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueOutputTimeoutGeneration) { 20225778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 20235778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20245778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20265778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueOutputPending); 20275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2028c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, -EAGAIN); 20295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20355778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatReleaseOutputBuffer: 20365778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 20373f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 20385778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 20395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2040251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 2041c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 20425778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2043251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2044251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2045251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 20465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20485778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onReleaseOutputBuffer(msg); 20495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2050c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatSignalEndOfInputStream: 20557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 20563f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 20577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 20587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 2059251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 2060c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 20617cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 2062251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2063251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2064251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 20657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 20667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 20677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 20687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->signalEndOfInputStream(); 20697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 20707cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 20717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 20725778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetBuffers: 20735778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 20743f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 20755778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 2076e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // Unfortunately widevine legacy source requires knowing all of the 2077e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // codec input buffers, so we have to provide them even in async mode. 2078e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar int32_t widevine = 0; 2079e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->findInt32("widevine", &widevine); 20805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2081e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) { 2082c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 20835778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2084251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2085251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2086251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20895778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 20915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<sp<ABuffer> > *dstBuffers; 20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber dstBuffers->clear(); 20965778822d86b0337407514b9372562b86edfa91cdAndreas Huber const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 20975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20985778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < srcBuffers.size(); ++i) { 20995778822d86b0337407514b9372562b86edfa91cdAndreas Huber const BufferInfo &info = srcBuffers.itemAt(i); 21005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2101ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber dstBuffers->push_back( 21021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (portIndex == kPortIndexInput && mCrypto != NULL) 2103ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ? info.mEncryptedData : info.mData); 21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(replyID); 21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21095778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21105778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatFlush: 21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 21123f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 2116c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2118251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2119251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 21240e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // TODO: skip flushing if already FLUSHED 21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(FLUSHING); 21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21275778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->signalFlush(); 21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 21295778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2132e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar case kWhatGetInputFormat: 21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetOutputFormat: 21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 2135e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> format = 2136e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat); 2137e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 21383f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2141e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((mState != CONFIGURED && mState != STARTING && 21420e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != STARTED && mState != FLUSHING && 21430e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != FLUSHED) 2144e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar || format == NULL) { 2145c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 2147251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 2148251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 2149251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 2153e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar response->setMessage("format", format); 21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2158496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 2159496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 2160496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mCodec->signalRequestIDRFrame(); 2161496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 2162496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 2163496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 2164575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber case kWhatRequestActivityNotification: 2165575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber { 2166575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(mActivityNotify == NULL); 2167575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(msg->findMessage("notify", &mActivityNotify)); 2168575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2169575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 2170575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber break; 2171575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2172575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2173717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo case kWhatGetName: 2174717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo { 21753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2176717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->senderAwaitsResponse(&replyID)); 2177717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2178717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.empty()) { 2179c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 2180717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2181717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2182717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2183717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response = new AMessage; 2184717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->setString("name", mComponentName.c_str()); 2185717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->postReply(replyID); 2186717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2187717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2188717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2189a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber case kWhatSetParameters: 2190a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber { 21913f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2192a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 2193a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2194a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> params; 2195a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->findMessage("params", ¶ms)); 2196a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2197a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber status_t err = onSetParameters(params); 2198a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2199c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 2200a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber break; 2201a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 2202a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22088ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) { 22098ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.clear(); 22108ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22118ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber size_t i = 0; 22128ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber for (;;) { 22138ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd; 2214a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) { 22158ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 22168ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 22178ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22188ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.push_back(csd); 22198ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ++i; 22208ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 22218ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 2222a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("Found %zu pieces of codec specific data.", mCSD.size()); 22238ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 22248ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22258ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 22268ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK(!mCSD.empty()); 22278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22287bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo *info = 22297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar &mPortBuffers[kPortIndexInput].itemAt(bufferIndex); 22308ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22318ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd = *mCSD.begin(); 22328ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.erase(mCSD.begin()); 22338ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22348ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber const sp<ABuffer> &codecInputData = 22358ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber (mCrypto != NULL) ? info->mEncryptedData : info->mData; 22368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (csd->size() > codecInputData->capacity()) { 22388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return -EINVAL; 22398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 22408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22418ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber memcpy(codecInputData->data(), csd->data(), csd->size()); 22428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber AString errorDetailMsg; 22448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 22468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("index", bufferIndex); 22478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("offset", 0); 22488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("size", csd->size()); 22498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt64("timeUs", 0ll); 22508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 22518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setPointer("errorDetailMsg", &errorDetailMsg); 22528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return onQueueInputBuffer(msg); 22548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 22558ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 22565778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) { 22577541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (newState == INITIALIZED || newState == UNINITIALIZED) { 22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber delete mSoftRenderer; 22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer = NULL; 22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto.clear(); 2262f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar handleSetSurface(NULL); 22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2264671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInputFormat.clear(); 22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat.clear(); 22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagStickyError; 2269e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagIsEncoder; 2270e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 2271c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 2272251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 2273575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2274575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2275c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback.clear(); 22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2278717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (newState == UNINITIALIZED) { 2279671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // return any straggling buffers, e.g. if we got here on an error 2280671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar returnBuffersToCodec(); 2281671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 2282aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // The component is gone, mediaserver's probably back up already 2283aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // but should definitely be back up should we try to instantiate 2284aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // another component.. and the cycle continues. 2285aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags &= ~kFlagSawMediaServerDie; 2286717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2287717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 22885778822d86b0337407514b9372562b86edfa91cdAndreas Huber mState = newState; 22895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22905778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 22912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 22922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang updateBatteryStat(); 22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22955778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() { 22965778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23005778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 23027bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23095778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify != NULL) { 23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> msg = info->mNotify; 23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mOwnedByClient = false; 23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexInput) { 23157fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar /* no error, just returning buffers */ 23167fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar msg->setInt32("err", OK); 23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->post(); 23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].clear(); 23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23255778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers( 23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex, const sp<AMessage> &msg) { 23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2329609b815a3131d22da38b2f452faa9f89daad4039Andy Hung uint32_t bufferID; 2330609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mBufferID == bufferID) { 23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mNotify == NULL); 23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("reply", &info->mNotify)); 23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2341475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mFormat = 2342475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat; 23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].push_back(i); 23445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23455778822d86b0337407514b9372562b86edfa91cdAndreas Huber return i; 23465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 23505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset; 23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size; 23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 23615778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("offset", &offset)); 23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23654b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples; 23664b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples; 23674b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *key; 23684b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *iv; 23694b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 23704b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 23714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // We allow the simpler queueInputBuffer API to be used even in 23724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // secure mode, by fabricating a single unencrypted subSample. 23734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::SubSample ss; 23744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 23754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (msg->findSize("size", &size)) { 23764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto != NULL) { 23774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfClearData = size; 23784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfEncryptedData = 0; 23794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 23804b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples = &ss; 23814b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples = 1; 23824b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber key = NULL; 23834b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber iv = NULL; 23844b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 23854b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } else { 23864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto == NULL) { 23874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber return -EINVAL; 23884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 23894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 23904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 23914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findSize("numSubSamples", &numSubSamples)); 23924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("key", (void **)&key)); 23934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("iv", (void **)&iv)); 23944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 23954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int32_t tmp; 23964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findInt32("mode", &tmp)); 23974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 23984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber mode = (CryptoPlugin::Mode)tmp; 23994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size = 0; 24014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber for (size_t i = 0; i < numSubSamples; ++i) { 24024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfClearData; 24034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfEncryptedData; 24044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 24054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 24064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 24075778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexInput].size()) { 24085778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 24095778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24115778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24175778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (offset + size > info->mData->capacity()) { 24185778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 24195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24215778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> reply = info->mNotify; 24225778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->setRange(offset, size); 24235778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt64("timeUs", timeUs); 24245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24255778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_EOS) { 24265778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("eos", true); 24275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24295778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_CODECCONFIG) { 24305778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("csd", true); 24315778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mCrypto != NULL) { 24341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (size > info->mEncryptedData->capacity()) { 24351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -ERANGE; 2436ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2437ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 24385b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg; 24395b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 24405b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 2441fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong ssize_t result = mCrypto->decrypt( 24421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (mFlags & kFlagIsSecure) != 0, 24431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber key, 24441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber iv, 24451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mode, 2446c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info->mSharedEncryptedBuffer, 2447c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker offset, 24484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples, 24494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples, 24505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mData->base(), 24515b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg); 24521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 2453fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong if (result < 0) { 2454fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong return result; 2455ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2456ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2457fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong info->mData->setRange(0, result); 2458ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2459ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 24607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 24617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 24627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 24637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 24647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 24652d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber reply->setBuffer("buffer", info->mData); 24665778822d86b0337407514b9372562b86edfa91cdAndreas Huber reply->post(); 24675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24685b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mNotify = NULL; 24695b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 24705778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 24715778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 24725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 24745778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 24755778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 24765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24775778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t render; 24785778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("render", &render)) { 24795778822d86b0337407514b9372562b86edfa91cdAndreas Huber render = 0; 24805778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24820e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 24835778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 24845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24865778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexOutput].size()) { 24875778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 24885778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24905778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 24915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24925778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 24935778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 24945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 24955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 24977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 24987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 24997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 25007bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 25017bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 250279ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou if (render && info->mData != NULL && info->mData->size() != 0) { 25035778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->setInt32("render", true); 25045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2505fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar int64_t timestampNs = 0; 2506fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (msg->findInt64("timestampNs", ×tampNs)) { 2507fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar info->mNotify->setInt64("timestampNs", timestampNs); 2508fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } else { 2509fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // TODO: it seems like we should use the timestamp 2510fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // in the (media)buffer as it potentially came from 2511fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // an input surface, but we did not propagate it prior to 2512fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // API 20. Perhaps check for target SDK version. 2513fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0 2514fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 251547aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar ALOGV("using buffer PTS of %" PRId64, timestampNs); 2516fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar timestampNs *= 1000; 2517fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2518fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif 2519fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2520fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 25215778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mSoftRenderer != NULL) { 25225778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer->render( 2523475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mData->data(), info->mData->size(), 2524475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu timestampNs, NULL, info->mFormat); 25255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25285778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->post(); 25295778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 25305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25315778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 25325778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 25335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25345778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 25355778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 25365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25375778822d86b0337407514b9372562b86edfa91cdAndreas Huber List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 25385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25395778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (availBuffers->empty()) { 25405778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EAGAIN; 25415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 25425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25435778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index = *availBuffers->begin(); 25445778822d86b0337407514b9372562b86edfa91cdAndreas Huber availBuffers->erase(availBuffers->begin()); 25455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25465778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 25475778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(!info->mOwnedByClient); 25487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 25497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 25507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = true; 255103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar 255203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar // set image-data 255303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat != NULL) { 255403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar sp<ABuffer> imageData; 255503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findBuffer("image-data", &imageData)) { 255603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setBuffer("image-data", imageData); 255703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 255803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar int32_t left, top, right, bottom; 255903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) { 256003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setRect("crop-rect", left, top, right, bottom); 256103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 256203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 25637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 25645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25655778822d86b0337407514b9372562b86edfa91cdAndreas Huber return index; 25665778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 25675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 25681dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::connectToSurface(const sp<Surface> &surface) { 25691dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = OK; 25701dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (surface != NULL) { 25711dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = native_window_api_connect(surface.get(), NATIVE_WINDOW_API_MEDIA); 25721dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == BAD_VALUE) { 25731dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGI("native window already connected. Assuming no change of surface"); 25741dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } else if (err != OK) { 25751dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGE("native_window_api_connect returned an error: %s (%d)", strerror(-err), err); 25761dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 25771dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 25781dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 25791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 25807541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 25811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::disconnectFromSurface() { 25821dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = OK; 2583f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar if (mSurface != NULL) { 25841dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = native_window_api_disconnect(mSurface.get(), NATIVE_WINDOW_API_MEDIA); 25857541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 25861dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar ALOGW("native_window_api_disconnect returned an error: %s (%d)", strerror(-err), err); 25877541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 25881dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar // assume disconnected even on error 2589f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar mSurface.clear(); 25907541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 25911dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 25921dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar} 25937541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 25941dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnarstatus_t MediaCodec::handleSetSurface(const sp<Surface> &surface) { 25951dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar status_t err = OK; 25961dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (mSurface != NULL) { 25971dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar (void)disconnectFromSurface(); 25981dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar } 2599f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar if (surface != NULL) { 26001dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar err = connectToSurface(surface); 26011dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar if (err == OK) { 26021dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar mSurface = surface; 26037541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 26047541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 26051dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar return err; 26067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber} 26077541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 2608c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() { 2609c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2610c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) { 2611c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2612c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_INPUT_AVAILABLE); 2613c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2614c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2615c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2616c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2617c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2618c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() { 2619c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2620c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) { 2621c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang const sp<ABuffer> &buffer = 2622c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mPortBuffers[kPortIndexOutput].itemAt(index).mData; 2623c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2624c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE); 2625c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2626c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("offset", buffer->offset()); 2627c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("size", buffer->size()); 2628c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2629c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int64_t timeUs; 2630c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2631c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2632c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt64("timeUs", timeUs); 2633c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2634c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t omxFlags; 2635c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 2636c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2637c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang uint32_t flags = 0; 2638c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 2639c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_SYNCFRAME; 2640c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2641c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 2642c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_CODECCONFIG; 2643c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2644c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_EOS) { 2645c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_EOS; 2646c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2647c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2648c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("flags", flags); 2649c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2650c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2651c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2652c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2653c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2654749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) { 2655c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2656c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2657c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_ERROR); 2658c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("err", err); 2659749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setInt32("actionCode", actionCode); 2660749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang 2661749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang if (detail != NULL) { 2662749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setString("detail", detail); 2663749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang } 2664c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2665c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2666c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2667c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2668c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2669c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() { 2670c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2671c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2672c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED); 2673c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("format", mOutputFormat); 2674c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2675c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2676c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2677c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2678c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2679575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() { 2680575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (mActivityNotify == NULL) { 2681575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber return; 2682575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2683575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2684e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang bool isErrorOrOutputChanged = 2685e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang (mFlags & (kFlagStickyError 2686575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber | kFlagOutputBuffersChanged 2687e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang | kFlagOutputFormatChanged)); 2688e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2689e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged 2690575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexInput].empty() 2691575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexOutput].empty()) { 2692e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("input-buffers", 2693e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexInput].size()); 2694e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2695e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged) { 2696e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang // we want consumer to dequeue as many times as it can 2697e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", INT32_MAX); 2698e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } else { 2699e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", 2700e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexOutput].size()); 2701e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } 2702575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify->post(); 2703575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2704575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2705575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 2706575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2707a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 27081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 2709a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber msg->setMessage("params", params); 2710a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2711a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> response; 2712a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return PostAndAwaitResponse(msg, &response); 2713a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2714a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2715a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 2716a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber mCodec->signalSetParameters(params); 2717a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2718a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return OK; 2719a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2720a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2721e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData( 2722e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const sp<ABuffer> &buffer) { 2723e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber AString mime; 2724e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber CHECK(mOutputFormat->findString("mime", &mime)); 2725e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2726e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 2727e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Codec specific data should be SPS and PPS in a single buffer, 2728e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // each prefixed by a startcode (0x00 0x00 0x00 0x01). 2729e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // We separate the two and put them into the output format 2730e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // under the keys "csd-0" and "csd-1". 2731e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2732e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber unsigned csdIndex = 0; 2733e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2734e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *data = buffer->data(); 2735e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t size = buffer->size(); 2736e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2737e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *nalStart; 2738e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t nalSize; 2739e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 2740e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber sp<ABuffer> csd = new ABuffer(nalSize + 4); 2741e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data(), "\x00\x00\x00\x01", 4); 2742e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data() + 4, nalStart, nalSize); 2743e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2744e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer( 2745a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes AStringPrintf("csd-%u", csdIndex).c_str(), csd); 2746e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2747e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ++csdIndex; 2748e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2749e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2750e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (csdIndex != 2) { 2751e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return ERROR_MALFORMED; 2752e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2753e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 2754e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // For everything else we just stash the codec specific data into 2755e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the output format as a single piece of csd under "csd-0". 2756e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer("csd-0", buffer); 2757e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2758e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2759e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return OK; 2760e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} 2761e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 27622606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() { 27632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mState == CONFIGURED && !mBatteryStatNotified) { 27642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier& notifier(BatteryNotifier::getInstance()); 27652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 27662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mIsVideo) { 27672606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStartVideo(); 27682606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else { 27692606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStartAudio(); 27702606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 27712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 27722606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = true; 27732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else if (mState == UNINITIALIZED && mBatteryStatNotified) { 27742606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier& notifier(BatteryNotifier::getInstance()); 27752606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 27762606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mIsVideo) { 27772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStopVideo(); 27782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else { 27792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStopAudio(); 27802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 27812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 27822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = false; 27832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 27842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 27852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 27865778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 2787