MediaCodec.cpp revision 48a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/* 25778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Copyright 2012, The Android Open Source Project 35778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 45778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 55778822d86b0337407514b9372562b86edfa91cdAndreas Huber * you may not use this file except in compliance with the License. 65778822d86b0337407514b9372562b86edfa91cdAndreas Huber * You may obtain a copy of the License at 75778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 85778822d86b0337407514b9372562b86edfa91cdAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 95778822d86b0337407514b9372562b86edfa91cdAndreas Huber * 105778822d86b0337407514b9372562b86edfa91cdAndreas Huber * Unless required by applicable law or agreed to in writing, software 115778822d86b0337407514b9372562b86edfa91cdAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 125778822d86b0337407514b9372562b86edfa91cdAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135778822d86b0337407514b9372562b86edfa91cdAndreas Huber * See the License for the specific language governing permissions and 145778822d86b0337407514b9372562b86edfa91cdAndreas Huber * limitations under the License. 155778822d86b0337407514b9372562b86edfa91cdAndreas Huber */ 165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 175778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0 185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "MediaCodec" 19fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#include <inttypes.h> 205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include "include/avc_utils.h" 225778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include "include/SoftwareRenderer.h" 235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IBatteryStats.h> 25c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h> 2667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <binder/IPCThreadState.h> 272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <binder/IServiceManager.h> 28c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/MemoryDealer.h> 291a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian#include <gui/Surface.h> 30ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h> 3167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu#include <media/IResourceManagerService.h> 325778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 335778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/ADebug.h> 345778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/foundation/AMessage.h> 355b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h> 36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/hexdump.h> 375778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/ACodec.h> 387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden#include <media/stagefright/BufferProducerWrapper.h> 392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <media/stagefright/MediaCodec.h> 406f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen#include <media/stagefright/MediaCodecList.h> 41e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber#include <media/stagefright/MediaDefs.h> 425778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MediaErrors.h> 43744f5739019d1fd917f981e740b353c3d73fd1a8David Smith#include <media/stagefright/MediaFilter.h> 445778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/MetaData.h> 455778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/stagefright/NativeWindowWrapper.h> 462606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <private/android_filesystem_config.h> 472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Log.h> 482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang#include <utils/Singleton.h> 49e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 505778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android { 515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic inline int getCallingPid() { 5367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return IPCThreadState::self()->getCallingPid(); 5467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 5567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 5667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic int64_t getId(sp<IResourceManagerClient> client) { 5767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (int64_t) client.get(); 5867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 5967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic bool isResourceError(status_t err) { 6167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (err == OMX_ErrorInsufficientResources); 6267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 6367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustatic const int kMaxRetry = 2; 6567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wustruct ResourceManagerClient : public BnResourceManagerClient { 6767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ResourceManagerClient(MediaCodec* codec) : mMediaCodec(codec) {} 6867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 6967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu virtual bool reclaimResource() { 7067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<MediaCodec> codec = mMediaCodec.promote(); 7167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (codec == NULL) { 7267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // codec is already gone. 7367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return true; 7467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 7567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err = codec->release(); 7667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 7767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerClient failed to release codec with err %d", err); 7867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 7967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return (err == OK); 8067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 8167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 828f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu virtual String8 getName() { 838f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu String8 ret; 848f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu sp<MediaCodec> codec = mMediaCodec.promote(); 858f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu if (codec == NULL) { 868f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu // codec is already gone. 878f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu return ret; 888f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 898f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu 908f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu AString name; 918f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu if (codec->getName(&name) == OK) { 928f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu ret.setTo(name.c_str()); 938f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 948f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu return ret; 958f9dd872366f54b6260506c75c3d0cc3f9f73f81Ronghua Wu } 9667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 9767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected: 9867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu virtual ~ResourceManagerClient() {} 9967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate: 10167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu wp<MediaCodec> mMediaCodec; 10267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 10367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient); 10467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}; 10567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 1062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> { 1072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier(); 108d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang virtual ~BatteryNotifier(); 1092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStartVideo(); 1112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStopVideo(); 1122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStartAudio(); 1132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStopAudio(); 114d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang void onBatteryStatServiceDied(); 1152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate: 117d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang struct DeathNotifier : public IBinder::DeathRecipient { 118d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang DeathNotifier() {} 119d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang virtual void binderDied(const wp<IBinder>& /*who*/) { 120d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang BatteryNotifier::getInstance().onBatteryStatServiceDied(); 121d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 122d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang }; 123d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 124d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex mLock; 1252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang int32_t mVideoRefCount; 1262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang int32_t mAudioRefCount; 1272606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang sp<IBatteryStats> mBatteryStatService; 128d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<DeathNotifier> mDeathNotifier; 129d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 130d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> getBatteryService_l(); 131d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 132d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier); 1332606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}; 1342606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1352606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier) 1362606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() : 1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount(0), 1392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount(0) { 140d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 141d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 142d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() { 143d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mBatteryStatService != NULL) { 144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return mBatteryStatService; 145d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 146d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // get battery service from service manager 1472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang const sp<IServiceManager> sm(defaultServiceManager()); 1482606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (sm != NULL) { 1492606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang const String16 name("batterystats"); 150d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService = 151d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang interface_cast<IBatteryStats>(sm->getService(name)); 1522606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mBatteryStatService == NULL) { 1532606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGE("batterystats service unavailable!"); 154d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return NULL; 155d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 156d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier = new DeathNotifier(); 15745c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang IInterface::asBinder(mBatteryStatService)->linkToDeath(mDeathNotifier); 158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // notify start now if media already started 159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount > 0) { 160d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService->noteStartVideo(AID_MEDIA); 161d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 162d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount > 0) { 163d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService->noteStartAudio(AID_MEDIA); 164d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 165d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 166d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return mBatteryStatService; 167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() { 170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mDeathNotifier != NULL) { 171d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang IInterface::asBinder(mBatteryStatService)-> 172d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang unlinkToDeath(mDeathNotifier); 1732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1742606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1752606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1762606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() { 177d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 178d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 179d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount == 0 && batteryService != NULL) { 180d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStartVideo(AID_MEDIA); 1812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount++; 1832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() { 186d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mVideoRefCount == 0) { 1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGW("BatteryNotifier::noteStop(): video refcount is broken!"); 1892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang return; 1902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 192d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 19345c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang 19445c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang mVideoRefCount--; 195d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount == 0 && batteryService != NULL) { 196d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStopVideo(AID_MEDIA); 1972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 2002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() { 201d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 202d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 203d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount == 0 && batteryService != NULL) { 204d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStartAudio(AID_MEDIA); 2052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount++; 2072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 2082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 2092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() { 210d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 2112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mAudioRefCount == 0) { 2122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!"); 2132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang return; 2142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 216d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 21745c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang 21845c765da4d67088ea7ce0fab438300682c3914f0Chong Zhang mAudioRefCount--; 219d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount == 0 && batteryService != NULL) { 220d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStopAudio(AID_MEDIA); 2212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2222606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 223d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 224d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() { 225d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 226d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService.clear(); 227d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier.clear(); 228d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // Do not reset mVideoRefCount and mAudioRefCount here. The ref 229d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // counting is independent of the battery service availability. 230d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // We need this if battery service becomes available after media 231d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // started. 232d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 233d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 23467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() { 23567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 23667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 23767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() { 23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService != NULL) { 23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu IInterface::asBinder(mService)->unlinkToDeath(this); 24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() { 24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IServiceManager> sm = defaultServiceManager(); 24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IBinder> binder = sm->getService(String16("media.resource_manager")); 24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService = interface_cast<IResourceManagerService>(binder); 24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("Failed to get ResourceManagerService"); 24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 251e4237177a4a3eea059cd74247b2d770d301a8230Ronghua Wu IInterface::asBinder(mService)->linkToDeath(this); 25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 25467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) { 25567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerService died."); 25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService.clear(); 25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource( 26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int pid, 26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int64_t clientId, 26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const sp<IResourceManagerClient> client, 26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const Vector<MediaResource> &resources) { 26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService->addResource(pid, clientId, client, resources); 27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) { 27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService->removeResource(clientId); 27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource( 28167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int callingPid, const Vector<MediaResource> &resources) { 28267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 28367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 28467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return false; 28567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return mService->reclaimResource(callingPid, resources); 28767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 28867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 2895778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 2905778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType( 291251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) { 2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = new MediaCodec(looper); 2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 294251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(mime, true /* nameIsType */, encoder); 295251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 296251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 297251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 2995778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3015778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 3025778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName( 303251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const sp<ALooper> &looper, const char *name, status_t *err) { 3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = new MediaCodec(looper); 3055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 306251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */); 307251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 308251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 309251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 310251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 3115778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3135778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper) 3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber : mState(UNINITIALIZED), 3155778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper(looper), 31692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar mCodec(NULL), 3177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID(0), 3185778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags(0), 319251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError(OK), 3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer(NULL), 321ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mResourceManagerClient(new ResourceManagerClient(this)), 322ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar mResourceManagerService(new ResourceManagerServiceProxy()), 3232606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified(false), 3242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mIsVideo(false), 32567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoWidth(0), 32667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoHeight(0), 3275778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputTimeoutGeneration(0), 3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID(0), 3295778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputTimeoutGeneration(0), 3306507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mDequeueOutputReplyID(0), 3313d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHaveInputSurface(false), 3323d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers(false) { 3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3355778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() { 3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, UNINITIALIZED); 33767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 3415778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse( 3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &msg, sp<AMessage> *response) { 3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = msg->postAndAwaitResponse(response); 3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3495778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!(*response)->findInt32("err", &err)) { 3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = OK; 3515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 356c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static 3573f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) { 358c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 359c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->setInt32("err", err); 360c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 361c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 362c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 363dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) { 36467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->init(); 36567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 366671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // save init parameters for reset 367671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitName = name; 368671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitNameIsType = nameIsType; 369671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitIsEncoder = encoder; 370671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 3715778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Current video decoders do not return from OMX_FillThisBuffer 3725778822d86b0337407514b9372562b86edfa91cdAndreas Huber // quickly, violating the OpenMAX specs, until that is remedied 3735778822d86b0337407514b9372562b86edfa91cdAndreas Huber // we need to invest in an extra looper to free the main event 3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber // queue. 375744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 376bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) { 377744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mCodec = new ACodec; 378744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else if (!nameIsType 379bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung && !strncasecmp(name.c_str(), "android.filter.", 15)) { 380744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mCodec = new MediaFilter; 381744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else { 382744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return NAME_NOT_FOUND; 383744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 384744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 38567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu bool secureCodec = false; 386dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) { 38767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 3886f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } else { 3896f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen AString tmp = name; 3906f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (tmp.endsWith(".secure")) { 39167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu secureCodec = true; 3926f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen tmp.erase(tmp.size() - 7, 7); 3936f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 39460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); 39548a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung if (mcl == NULL) { 39648a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung mCodec = NULL; // remove the codec. 39748a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung return NO_INIT; // if called from Java should raise IOException 39848a31bf3f1c1ed5953a4e64f71cdf528f3a38ee5Andy Hung } 3996f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); 4006f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (codecIdx >= 0) { 40160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); 40260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<AString> mimes; 40360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar info->getSupportedMimes(&mimes); 40460b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t i = 0; i < mimes.size(); i++) { 40560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (mimes[i].startsWith("video/")) { 40667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 40760b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar break; 4086f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4096f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4106f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 41367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 41467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // video codec needs dedicated looper 4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mCodecLooper == NULL) { 4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper = new ALooper; 4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->setName("CodecLooper"); 4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->registerHandler(mCodec); 4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(mCodec); 4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4265778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(this); 4275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this)); 4295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4301d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatInit, this); 4315778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setString("name", name); 4325778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("nameIsType", nameIsType); 4335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 4355778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("encoder", encoder); 4365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 43867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 43967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 44067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec; 441c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec; 442c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(String8(type), String8(subtype), 1)); 44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 44467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 44567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 44667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 44767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 44867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 44967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 45067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 45167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 45267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 45367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 45467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 45567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 45667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 45767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 4585778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) { 4611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetCallback, this); 462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("callback", callback); 463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response; 465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang return PostAndAwaitResponse(msg, &response); 466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 4685778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure( 4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &format, 4701a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian const sp<Surface> &nativeWindow, 4711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const sp<ICrypto> &crypto, 4725778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags) { 4731d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigure, this); 4745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 47567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 47667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("width", &mVideoWidth); 47767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("height", &mVideoHeight); 47867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 47967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 4805778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setMessage("format", format); 4815778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 4825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4835778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nativeWindow != NULL) { 4841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber msg->setObject( 4851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber "native-window", 4861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber new NativeWindowWrapper(nativeWindow)); 4871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 4881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 4891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (crypto != NULL) { 4901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber msg->setPointer("crypto", crypto.get()); 4915778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 49367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // save msg for reset 49467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mConfigureMsg = msg; 495f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 49667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 49767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 49867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = (mFlags & kFlagIsSecure) ? 49967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu kResourceSecureCodec : kResourceNonSecureCodec; 500c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec; 501c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(String8(type), String8(subtype), 1)); 50267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 50367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 50467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1)); 50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 50967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 51067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 51167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 512f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 51367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 51467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 51567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK && err != INVALID_OPERATION) { 51667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // MediaCodec now set state to UNINITIALIZED upon any fatal error. 51767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // To maintain backward-compatibility, do a reset() to put codec 51867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // back into INITIALIZED state. 51967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // But don't reset if the err is INVALID_OPERATION, which means 52067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the configure failure is due to wrong state. 52167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 52267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("configure failed with err 0x%08x, resetting...", err); 52367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu reset(); 52467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 52567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 52667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 52767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 528f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang } 529f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang return err; 5305778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface( 5337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 5341d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this); 5357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 5367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 5377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = PostAndAwaitResponse(msg, &response); 5387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (err == NO_ERROR) { 5397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // unwrap the sp<IGraphicBufferProducer> 5407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 5417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden bool found = response->findObject("input-surface", &obj); 5427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(found); 5437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<BufferProducerWrapper> wrapper( 5447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden static_cast<BufferProducerWrapper*>(obj.get())); 5457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden *bufferProducer = wrapper->getBufferProducer(); 5467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 5477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGW("createInputSurface failed, err=%d", err); 5487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 5497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return err; 5507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 5517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() { 55367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mIsVideo) { 55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return 0; 55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 55667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu uint64_t size = 0; 55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]); 55967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (size_t i = 0; i < portNum; ++i) { 56067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // TODO: this is just an estimation, we should get the real buffer size from ACodec. 56167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2; 56267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return size; 56467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 566c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wuvoid MediaCodec::addResource(const String8 &type, const String8 &subtype, uint64_t value) { 56767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 568c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(type, subtype, value)); 56967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->addResource( 57067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources); 57167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 57267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 5735778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() { 5741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, this); 5755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 57667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 57867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = (mFlags & kFlagIsSecure) ? 57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu kResourceSecureCodec : kResourceNonSecureCodec; 580c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec; 581c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu resources.push_back(MediaResource(String8(type), String8(subtype), 1)); 58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 58467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1)); 58567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 58667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 58767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 58867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 58967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 59067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Recover codec from previous error before retry start. 59267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = reset(); 59367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to reset codec"); 59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 59867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(mConfigureMsg, &response); 59967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 60067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to configure codec"); 60167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 60267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 60367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 60467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 60567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 60667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 60767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 60867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 60967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 61067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 61167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 6125778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6145778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() { 6151d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, this); 6165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6175778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 6185778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 6195778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 621c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() { 6221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRelease, this); 623c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 624c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response; 625c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return PostAndAwaitResponse(msg, &response); 626c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 627c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 628671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() { 629671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar /* When external-facing MediaCodec object is created, 630671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar it is already initialized. Thus, reset is essentially 631671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar release() followed by init(), plus clearing the state */ 632671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 633671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar status_t err = release(); 634671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 635671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // unregister handlers 636671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodec != NULL) { 637671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodecLooper != NULL) { 638671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodecLooper->unregisterHandler(mCodec->id()); 639671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } else { 640671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(mCodec->id()); 641671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 642671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodec = NULL; 643671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 644671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(id()); 645671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 646671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mFlags = 0; // clear all flags 647251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 648671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 649671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // reset state not reset by setState(UNINITIALIZED) 650671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mReplyID = 0; 651671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputReplyID = 0; 652671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputReplyID = 0; 653671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputTimeoutGeneration = 0; 654671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputTimeoutGeneration = 0; 655671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mHaveInputSurface = false; 656671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 657671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (err == OK) { 658dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung err = init(mInitName, mInitNameIsType, mInitIsEncoder); 659671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 660671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar return err; 661671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar} 662671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 6635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer( 6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index, 6655778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset, 6665778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size, 6675778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t presentationTimeUs, 6685b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 6695b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 6705b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 6715b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 6725b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 6735b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 6741d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 6755778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 6765778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("offset", offset); 6775778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("size", size); 6785778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 6795778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 6805b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 6815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6825778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 6835778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 6845778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6864b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer( 6874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t index, 6884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t offset, 6894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples, 6904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples, 6914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t key[16], 6924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t iv[16], 6934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode, 6944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int64_t presentationTimeUs, 6955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 6965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 6975b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 6985b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 6995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 7005b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7011d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 7024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("index", index); 7034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("offset", offset); 7044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("subSamples", (void *)subSamples); 7054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("numSubSamples", numSubSamples); 7064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("key", (void *)key); 7074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("iv", (void *)iv); 7084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("mode", mode); 7094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 7104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("flags", flags); 7115b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 7124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber sp<AMessage> response; 7145b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber status_t err = PostAndAwaitResponse(msg, &response); 7155b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7165b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber return err; 7174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber} 7184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 7201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this); 7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7265778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7345778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer( 7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *index, 7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *offset, 7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *size, 7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t *presentationTimeUs, 7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t *flags, 7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs) { 7411d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this); 7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7445778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7455778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("offset", offset)); 7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("size", size)); 7535778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt64("timeUs", presentationTimeUs)); 7545778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt32("flags", (int32_t *)flags)); 7555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7565778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7575778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 7601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 7615778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7625778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("render", true); 7635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7645778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 768fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) { 7691d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 770fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setSize("index", index); 771fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt32("render", true); 772fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt64("timestampNs", timestampNs); 773fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 774fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar sp<AMessage> response; 775fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar return PostAndAwaitResponse(msg, &response); 776fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar} 777fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 7785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) { 7791d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7867cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() { 7871d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this); 7887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 7897cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 7907cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return PostAndAwaitResponse(msg, &response); 7917cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 7927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 7935778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 7941d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this); 7955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7965778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7975778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7985778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7995778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 8005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 8015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8025778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findMessage("format", format)); 8035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8045778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 8055778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 807e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const { 8081d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this); 809e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 810e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> response; 811e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar status_t err; 812e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 813e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return err; 814e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 815e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 816e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(response->findMessage("format", format)); 817e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 818e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return OK; 819e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar} 820e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 821717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const { 8221d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetName, this); 823717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 824717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response; 825717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo status_t err; 826717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 827717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return err; 828717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 829717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 830717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(response->findString("name", name)); 831717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 832717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return OK; 833717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo} 834717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 835e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const { 836e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 837e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("portIndex", kPortIndexInput); 838e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setPointer("buffers", buffers); 839e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("widevine", true); 840e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 841e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> response; 842e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar return PostAndAwaitResponse(msg, &response); 843e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar} 844e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 8455778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 8461d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexInput); 8485778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8505778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8515778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8525778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8545778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 8551d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8565778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexOutput); 8575778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8595778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8605778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8615778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8637bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) { 8647bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 8657bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, buffer, &format); 8667bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) { 8697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> buffer; 8707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, &buffer, format); 8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) { 8747bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 8757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexInput, index, buffer, &format); 8767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8780e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const { 8790e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar return mState == STARTED || mState == FLUSHED; 8800e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar} 8810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar 8827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat( 8837bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar size_t portIndex, size_t index, 8847bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> *buffer, sp<AMessage> *format) { 8857bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // use mutex instead of a context switch 8867bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar buffer->clear(); 8887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar format->clear(); 8890e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 8907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return INVALID_OPERATION; 8917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 8927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we do not want mPortBuffers to change during this section 8947bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we also don't want mOwnedByClient to change during this 8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 8967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 8977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar if (index < buffers->size()) { 8987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo &info = buffers->itemAt(index); 8997bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar if (info.mOwnedByClient) { 9000837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar // by the time buffers array is initialized, crypto is set 9010837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar if (portIndex == kPortIndexInput && mCrypto != NULL) { 9020837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar *buffer = info.mEncryptedData; 9030837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar } else { 9040837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar *buffer = info.mData; 9050837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar } 9067bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar *format = info.mFormat; 9077bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 9087bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 9097bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return OK; 9107bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 9117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 9125778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() { 9131d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFlush, this); 9145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9155778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 919496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() { 9201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatRequestIDRFrame, this))->post(); 921496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 922496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber return OK; 923496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 924496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 925575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 9261d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this); 927575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->setMessage("notify", notify); 928575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->post(); 929575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 930575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber//////////////////////////////////////////////////////////////////////////////// 9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9335778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() { 9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueInputPending) { 935c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION); 9365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9375778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 9395778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9425778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueOutputPending) { 943c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION); 9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9513f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 9520e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueInputPending))) { 954c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 956251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 957251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 958251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return true; 9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9635778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 9665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9753f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9780e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INVALID_OPERATION); 981251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 982251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung response->setInt32("err", getStickyError()); 9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputBuffersChanged) { 9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); 9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputFormatChanged) { 9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INFO_FORMAT_CHANGED); 9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexOutput); 9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<ABuffer> &buffer = 9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[kPortIndexOutput].itemAt(index).mData; 9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("offset", buffer->offset()); 10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("size", buffer->size()); 10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt64("timeUs", timeUs); 10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags = 0; 10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_SYNCFRAME; 10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10165778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_CODECCONFIG; 10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_EOS) { 10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_EOS; 10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("flags", flags); 10245778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10265778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 10275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10285778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10315778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 10325778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (msg->what()) { 10335778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatCodecNotify: 10345778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10355778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t what; 10365778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("what", &what)); 10375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (what) { 103992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatError: 10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1041251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung int32_t err, actionCode; 1042251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("err", &err)); 1043251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("actionCode", &actionCode)); 10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10459e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen ALOGE("Codec reported err %#x, actionCode %d, while in state %d", 10469e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen err, actionCode, mState); 1047251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err == DEAD_OBJECT) { 1048aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags |= kFlagSawMediaServerDie; 104952dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 1050aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1051aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 10525530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia bool sendErrorResponse = true; 10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (mState) { 10555778822d86b0337407514b9372562b86edfa91cdAndreas Huber case INITIALIZING: 10565778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(UNINITIALIZED); 10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10615778822d86b0337407514b9372562b86edfa91cdAndreas Huber case CONFIGURING: 10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1063c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1064c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : INITIALIZED); 10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10685778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTING: 10695778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1070c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1071c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : CONFIGURED); 10725778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10755778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STOPPING: 1076c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case RELEASING: 10775778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10785778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Ignore the error, assuming we'll still get 10795778822d86b0337407514b9372562b86edfa91cdAndreas Huber // the shutdown complete notification. 10805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10815530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 108203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 1083aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 108403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // MediaServer died, there definitely won't 108503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // be a shutdown complete notification after 108603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // all. 108703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 108803ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // note that we're directly going from 108903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // STOPPING->UNINITIALIZED, instead of the 109003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // usual STOPPING->INITIALIZED state. 109103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber setState(UNINITIALIZED); 10926e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (mState == RELEASING) { 10936e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 10946e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 109503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber (new AMessage)->postReply(mReplyID); 109603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber } 10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber case FLUSHING: 11015778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11029e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen if (actionCode == ACTION_CODE_FATAL) { 11039e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState(UNINITIALIZED); 11049e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } else { 11059e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState( 11069e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen (mFlags & kFlagIsAsync) ? FLUSHED : STARTED); 11079e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } 11085778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11095778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11110e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar case FLUSHED: 11125778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTED: 11135778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11145530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1117575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 11185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 1120c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1121c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1122251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1123251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1124251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1125251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1127251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1128251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1132251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1133c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 11345778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11375778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 11385778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11395530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1142575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1143c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1144251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung // actionCode in an uninitialized state is always fatal. 1145251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (mState == UNINITIALIZED) { 1146251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung actionCode = ACTION_CODE_FATAL; 1147251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1148c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1149251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1150251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1152251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1153251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1154251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1155251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1156251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1157251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1158251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1159251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1160c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11655530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (sendErrorResponse) { 1166251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(mReplyID, err); 11675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 117192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentAllocated: 11725778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11735778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, INITIALIZING); 11745778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZED); 117552dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags |= kFlagIsComponentAllocated; 11765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1177717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->findString("componentName", &mComponentName)); 11785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1179717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.startsWith("OMX.google.")) { 11803a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 11823a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags &= ~kFlagUsesSoftwareRenderer; 11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 118567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu String8 resourceType; 1186717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.endsWith(".secure")) { 11871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags |= kFlagIsSecure; 118867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resourceType = String8(kResourceSecureCodec); 11891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 11901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags &= ~kFlagIsSecure; 119167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resourceType = String8(kResourceNonSecureCodec); 11921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1193c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu 1194c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu const char *subtype = mIsVideo ? kResourceVideoCodec : kResourceAudioCodec; 1195c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu addResource(resourceType, String8(subtype), 1); 11961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 11975778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 11985778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11995778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 120192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentConfigured: 12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, CONFIGURING); 12045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12056507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden // reset input surface flag 12066507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = false; 12076507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 1208e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("input-format", &mInputFormat)); 1209e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("output-format", &mOutputFormat)); 1210e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 12113a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar int32_t usingSwRenderer; 12123a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer) 12133a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar && usingSwRenderer) { 12143a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 12153a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 12162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang setState(CONFIGURED); 12175778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 12185778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 122192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatInputSurfaceCreated: 12227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 122392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to initiateCreateInputSurface() 12247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = NO_ERROR; 12257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response = new AMessage(); 12267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (!msg->findInt32("err", &err)) { 12277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 12287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden msg->findObject("input-surface", &obj); 12297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(obj != NULL); 12307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setObject("input-surface", obj); 12316507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = true; 12327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 12337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 12347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 12367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 12377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 123992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatSignaledInputEOS: 12407cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 124192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to signalEndOfInputStream() 12427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response = new AMessage(); 12437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err; 12447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (msg->findInt32("err", &err)) { 12457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 12467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 12487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 12497cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12507cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 12517cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 125292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatBuffersAllocated: 12535778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 12547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 12555778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 12575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("%s buffers allocated", 12595778822d86b0337407514b9372562b86edfa91cdAndreas Huber portIndex == kPortIndexInput ? "input" : "output"); 12605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12615778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput 12625778822d86b0337407514b9372562b86edfa91cdAndreas Huber || portIndex == kPortIndexOutput); 12635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12645778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[portIndex].clear(); 12655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12665778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 12675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1268eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber sp<RefBase> obj; 1269eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber CHECK(msg->findObject("portDesc", &obj)); 1270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 127192cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar sp<CodecBase::PortDescription> portDesc = 127292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar static_cast<CodecBase::PortDescription *>(obj.get()); 12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber size_t numBuffers = portDesc->countBuffers(); 12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1276c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker size_t totalSize = 0; 1277c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker for (size_t i = 0; i < numBuffers; ++i) { 1278c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (portIndex == kPortIndexInput && mCrypto != NULL) { 1279c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker totalSize += portDesc->bufferAt(i)->capacity(); 1280c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1281c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1282c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1283c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (totalSize) { 1284c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker mDealer = new MemoryDealer(totalSize, "MediaCodec"); 1285c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1286c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1287eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber for (size_t i = 0; i < numBuffers; ++i) { 12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo info; 1289eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mBufferID = portDesc->bufferIDAt(i); 12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber info.mOwnedByClient = false; 1291eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mData = portDesc->bufferAt(i); 12925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (portIndex == kPortIndexInput && mCrypto != NULL) { 1294c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sp<IMemory> mem = mDealer->allocate(info.mData->capacity()); 1295ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info.mEncryptedData = 1296c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker new ABuffer(mem->pointer(), info.mData->capacity()); 1297c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info.mSharedEncryptedBuffer = mem; 1298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 1299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffers->push_back(info); 13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexOutput) { 13045778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState == STARTING) { 13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We're always allocating output buffers after 13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber // allocating input buffers, so this is a good 13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber // indication that now all buffers are allocated. 130867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 1309c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu String8 subtype; 1310c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu addResource( 1311c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu String8(kResourceGraphicMemory), 1312c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu subtype, 1313c721e71f4d7e3cd4fc9332fd55fb6942f54cec39Ronghua Wu getGraphicBufferSize()); 131467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 13155778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTED); 13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagOutputBuffersChanged; 1319575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 13205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13225778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13235778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 132592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatOutputFormatChanged: 13265778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13275778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("codec output format changed"); 13285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1329475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mSoftRenderer == NULL && 1330475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mNativeWindow != NULL && 13313a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar (mFlags & kFlagUsesSoftwareRenderer)) { 13325778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString mime; 13335778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("mime", &mime)); 13345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1335475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mime.startsWithIgnoreCase("video/")) { 1336475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mSoftRenderer = new SoftwareRenderer(mNativeWindow); 13375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13405778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat = msg; 1341e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1342e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagIsEncoder) { 1343e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Before we announce the format change we should 1344e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // collect codec specific data and amend the output 1345e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format as necessary. 1346e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagGatherCodecSpecificData; 1347c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagIsAsync) { 1348c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1349e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 1350e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagOutputFormatChanged; 1351e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber postActivityNotificationIfPossible(); 1352e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 13532514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 13542514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker // Notify mCrypto of video resolution changes 13552514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker if (mCrypto != NULL) { 13568140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar int32_t left, top, right, bottom, width, height; 13578140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { 13588140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(right - left + 1, bottom - top + 1); 13598140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } else if (mOutputFormat->findInt32("width", &width) 13608140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar && mOutputFormat->findInt32("height", &height)) { 13618140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(width, height); 13628140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } 13632514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 13642514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 13655778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 136892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFillThisBuffer: 13695778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13705778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexInput, msg); 13715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1372c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1373c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1374c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 13755778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 13765778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (!mCSD.empty()) { 13808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 13818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK_GE(index, 0); 13828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // If codec specific data had been specified as 13848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // part of the format in the call to configure and 13858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // if there's more csd left, we submit it here 13868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // clients only get access to input buffers once 13878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // this data has been exhausted. 13888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber status_t err = queueCSDInputBuffer(index); 13908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (err != OK) { 13928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ALOGE("queueCSDInputBuffer failed w/ error %d", 13938ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber err); 13948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1395251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1396575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1397575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 13988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber cancelPendingDequeueOperations(); 13998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 14008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 14018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 14028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1403c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 14046e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (!mHaveInputSurface) { 14053d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mState == FLUSHED) { 14063d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = true; 14073d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } else { 14083d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 14093d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 14106e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1411c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueInputPending) { 14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 14135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14145778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 1417575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1418575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 142392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatDrainThisBuffer: 14245778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14255778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexOutput, msg); 14265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1427c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1428c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1429c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 14305778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 14315778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14342d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 14352d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 14365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14375778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 14385778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", &omxFlags)); 14395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14405778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("omxFlags", omxFlags); 14415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagGatherCodecSpecificData) { 1443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // This is the very first output buffer after a 1444e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format change was signalled, it'll either contain 1445e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the one piece of codec specific data we can expect 1446e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // or there won't be codec specific data. 1447e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 1448e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber status_t err = 1449e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber amendOutputFormatWithCodecSpecificData(buffer); 1450e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1451e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (err != OK) { 1452e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ALOGE("Codec spit out malformed codec " 1453e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber "specific data!"); 1454e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1455e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1456e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1457e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 1458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1459c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagOutputFormatChanged; 1462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1463e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1464e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputBufferAvailable(); 1467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueOutputPending) { 14685778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 14695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14705778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 14715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 14725778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 1473575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1474575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 14755778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1476575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 14775778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14785778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 148092cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatEOS: 14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We already notify the client of this by using the 14835778822d86b0337407514b9372562b86edfa91cdAndreas Huber // corresponding flag in "onOutputBufferReady". 14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 148792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatShutdownCompleted: 14885778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1489c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == STOPPING) { 1490c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(INITIALIZED); 1491c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } else { 1492c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK_EQ(mState, RELEASING); 1493c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(UNINITIALIZED); 14946e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 1495c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 149652dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 149867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 149967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 150492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFlushCompleted: 15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15065530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (mState != FLUSHING) { 15075530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia ALOGW("received FlushCompleted message in state %d", 15085530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia mState); 15095530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia break; 15105530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia } 15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15120e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mFlags & kFlagIsAsync) { 15130e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(FLUSHED); 15140e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else { 15150e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(STARTED); 15160e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 15170e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } 15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15265778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15275778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatInit: 15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15313f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != UNINITIALIZED) { 1535c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZING); 15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString name; 15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("name", &name)); 15445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15455778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t nameIsType; 15465778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t encoder = false; 15470db280176bd3277e3256252d063f3712b1905ba9Andreas Huber CHECK(msg->findInt32("nameIsType", &nameIsType)); 15480db280176bd3277e3256252d063f3712b1905ba9Andreas Huber if (nameIsType) { 15495778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("encoder", &encoder)); 15505778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15525778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format = new AMessage; 15535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15545778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 15555778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("mime", name.c_str()); 15565778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", encoder); 15575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 15585778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("componentName", name.c_str()); 15595778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15615778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateAllocateComponent(format); 15625778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1565c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang case kWhatSetCallback: 1566c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang { 15673f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1568c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1570c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mState == UNINITIALIZED 1571c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang || mState == INITIALIZING 15720e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar || isExecuting()) { 15730e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // callback can't be set after codec is executing, 1574c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // or before it's initialized (as the callback 1575c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // will be cleared when it goes to INITIALIZED) 1576c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1577c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1578c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1579c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1580c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> callback; 1581c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->findMessage("callback", &callback)); 1582c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1583c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback = callback; 1584c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1585c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 1586c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGI("MediaCodec will operate in async mode"); 1587c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagIsAsync; 1588c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1589c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 1590c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1591c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1592c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 1593c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 1594c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1595c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1596c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 15975778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatConfigure: 15985778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15993f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16005778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 16015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16025778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != INITIALIZED) { 1603c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16045778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16075778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<RefBase> obj; 16085778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findObject("native-window", &obj)) { 16095778822d86b0337407514b9372562b86edfa91cdAndreas Huber obj.clear(); 16105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16125778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format; 16135778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("format", &format)); 16145778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (obj != NULL) { 16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setObject("native-window", obj); 16171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber status_t err = setNativeWindow( 16197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber static_cast<NativeWindowWrapper *>(obj.get()) 16207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ->getSurfaceTextureClient()); 16217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 16227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 1623c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 16247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber break; 16251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 16261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 16277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setNativeWindow(NULL); 16281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 16291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16307541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mReplyID = replyID; 16317541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setState(CONFIGURING); 16327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 16331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber void *crypto; 16341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (!msg->findPointer("crypto", &crypto)) { 16351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber crypto = NULL; 16365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto = static_cast<ICrypto *>(crypto); 16391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16405778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 16415778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 16425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16435778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & CONFIGURE_FLAG_ENCODE) { 16445778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", true); 1645e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagIsEncoder; 16465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber extractCSD(format); 16498ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateConfigureComponent(format); 16515778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16547cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatCreateInputSurface: 16557cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 16563f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16577cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 16587cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16597cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // Must be configured, but can't have been started yet. 16607cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (mState != CONFIGURED) { 1661c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16627cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 16637cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 16647cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16657cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 16667cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->initiateCreateInputSurface(); 16677cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 16687cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 16697cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStart: 16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 16723f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16750e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mState == FLUSHED) { 1676d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang setState(STARTED); 16773d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mHavePendingInputBuffers) { 16783d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 16793d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = false; 16803d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 16810e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 16820e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar PostReplyWithError(replyID, OK); 1683d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang break; 16840e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else if (mState != CONFIGURED) { 1685c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16865778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16875778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16895778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 16905778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTING); 16915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16925778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateStart(); 16935778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16965778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStop: 1697c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case kWhatRelease: 1698c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 1699aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber State targetState = 1700aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 1701aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 17023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 1704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 170533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 170633223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung && mState != INITIALIZED 17070e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar && mState != CONFIGURED && !isExecuting()) { 170833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 1) Permit release to shut down the component if allocated. 170933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 171033223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 2) We may be in "UNINITIALIZED" state already and 171152dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan // also shutdown the encoder/decoder without the 171203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // client being aware of this if media server died while 171303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // we were being stopped. The client would assume that 171403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // after stop() returned, it would be safe to call release() 171503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // and it should be in this case, no harm to allow a release() 171603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // if we're already uninitialized. 1717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response = new AMessage; 17186e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar status_t err = mState == targetState ? OK : INVALID_OPERATION; 17196e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar response->setInt32("err", err); 17206e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (err == OK && targetState == UNINITIALIZED) { 17216e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 17226e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1723c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber response->postReply(replyID); 1724c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 1725c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 1726c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 1727aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 1728aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // It's dead, Jim. Don't expect initiateShutdown to yield 1729aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // any useful results now... 1730aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(UNINITIALIZED); 17316e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (targetState == UNINITIALIZED) { 17326e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 17336e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1734aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (new AMessage)->postReply(replyID); 1735aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber break; 1736aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1737aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1738c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mReplyID = replyID; 1739aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 1740aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1741aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mCodec->initiateShutdown( 1742aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber msg->what() == kWhatStop /* keepComponentAllocated */); 1743c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputBuffer: 17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 17503f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 17525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1753c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1754c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1755c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1756c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1757c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1758c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 17596507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden if (mHaveInputSurface) { 17606507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden ALOGE("dequeueInputBuffer can't be used with input surface"); 1761c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 17626507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden break; 17636507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden } 17646507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueInputBuffer(replyID, true /* new request */)) { 17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1773c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueInputPending; 17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = replyID; 17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 17815778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 17821d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueInputTimedOut, this); 17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueInputTimeoutGeneration); 17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17905778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputTimedOut: 17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 17935778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 17945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueInputTimeoutGeneration) { 17965778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 17975778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueInputPending); 18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1802c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, -EAGAIN); 18035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18095778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatQueueInputBuffer: 18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18113f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18125778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1814251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1815c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18165778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1817251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1818251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1819251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onQueueInputBuffer(msg); 18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1824c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18265778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputBuffer: 18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18303f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1833c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1834c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1835c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1836c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1837c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1838c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1847c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueOutputPending; 18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = replyID; 18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 18555778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 18561d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueOutputTimedOut, this); 18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueOutputTimeoutGeneration); 18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18645778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputTimedOut: 18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 18675778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 18685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueOutputTimeoutGeneration) { 18705778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 18715778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18725778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueOutputPending); 18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1876c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, -EAGAIN); 18775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18815778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18835778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatReleaseOutputBuffer: 18845778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18853f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18865778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1888251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1889c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18905778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1891251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1892251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1893251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 18945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18965778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onReleaseOutputBuffer(msg); 18975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1898c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19027cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatSignalEndOfInputStream: 19037cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 19043f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 19067cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 1907251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1908c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 1910251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1911251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1912251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 19147cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 19157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 19167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->signalEndOfInputStream(); 19177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 19187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 19197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetBuffers: 19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19223f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 1924e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // Unfortunately widevine legacy source requires knowing all of the 1925e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // codec input buffers, so we have to provide them even in async mode. 1926e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar int32_t widevine = 0; 1927e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->findInt32("widevine", &widevine); 19285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1929e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) { 1930c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1932251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1933251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1934251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 19395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<sp<ABuffer> > *dstBuffers; 19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 19425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19435778822d86b0337407514b9372562b86edfa91cdAndreas Huber dstBuffers->clear(); 19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 19455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19465778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < srcBuffers.size(); ++i) { 19475778822d86b0337407514b9372562b86edfa91cdAndreas Huber const BufferInfo &info = srcBuffers.itemAt(i); 19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1949ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber dstBuffers->push_back( 19501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (portIndex == kPortIndexInput && mCrypto != NULL) 1951ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ? info.mEncryptedData : info.mData); 19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(replyID); 19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatFlush: 19595778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19603f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1963251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1964c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19655778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1966251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1967251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1968251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19695778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 19720e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // TODO: skip flushing if already FLUSHED 19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(FLUSHING); 19745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19755778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->signalFlush(); 19765778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1980e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar case kWhatGetInputFormat: 19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetOutputFormat: 19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1983e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> format = 1984e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat); 1985e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 19863f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19875778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1989e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((mState != CONFIGURED && mState != STARTING && 19900e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != STARTED && mState != FLUSHING && 19910e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != FLUSHED) 1992e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar || format == NULL) { 1993c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19945778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1995251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1996251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1997251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20005778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 2001e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar response->setMessage("format", format); 20025778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 20035778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 20045778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2006496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 2007496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 2008496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mCodec->signalRequestIDRFrame(); 2009496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 2010496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 2011496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 2012575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber case kWhatRequestActivityNotification: 2013575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber { 2014575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(mActivityNotify == NULL); 2015575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(msg->findMessage("notify", &mActivityNotify)); 2016575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2017575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 2018575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber break; 2019575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2020575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2021717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo case kWhatGetName: 2022717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo { 20233f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2024717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->senderAwaitsResponse(&replyID)); 2025717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2026717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.empty()) { 2027c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 2028717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2029717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2030717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2031717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response = new AMessage; 2032717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->setString("name", mComponentName.c_str()); 2033717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->postReply(replyID); 2034717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2035717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2036717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2037a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber case kWhatSetParameters: 2038a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber { 20393f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2040a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 2041a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2042a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> params; 2043a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->findMessage("params", ¶ms)); 2044a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2045a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber status_t err = onSetParameters(params); 2046a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2047c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 2048a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber break; 2049a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 2050a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 20515778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 20525778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 20535778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20545778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 20555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20568ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) { 20578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.clear(); 20588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber size_t i = 0; 20608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber for (;;) { 20618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd; 2062a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) { 20638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 20648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.push_back(csd); 20678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ++i; 20688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 2070a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("Found %zu pieces of codec specific data.", mCSD.size()); 20718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 20728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 20748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK(!mCSD.empty()); 20758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo *info = 20777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar &mPortBuffers[kPortIndexInput].itemAt(bufferIndex); 20788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd = *mCSD.begin(); 20808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.erase(mCSD.begin()); 20818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber const sp<ABuffer> &codecInputData = 20838ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber (mCrypto != NULL) ? info->mEncryptedData : info->mData; 20848ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20858ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (csd->size() > codecInputData->capacity()) { 20868ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return -EINVAL; 20878ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20888ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20898ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber memcpy(codecInputData->data(), csd->data(), csd->size()); 20908ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20918ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber AString errorDetailMsg; 20928ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 20948ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("index", bufferIndex); 20958ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("offset", 0); 20968ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("size", csd->size()); 20978ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt64("timeUs", 0ll); 20988ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 20998ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setPointer("errorDetailMsg", &errorDetailMsg); 21008ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 21018ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return onQueueInputBuffer(msg); 21028ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 21038ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 21045778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) { 21057541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (newState == INITIALIZED || newState == UNINITIALIZED) { 21065778822d86b0337407514b9372562b86edfa91cdAndreas Huber delete mSoftRenderer; 21075778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer = NULL; 21085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto.clear(); 21107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setNativeWindow(NULL); 21115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2112671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInputFormat.clear(); 21135778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat.clear(); 21145778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagStickyError; 2117e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagIsEncoder; 2118e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 2119c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 2120251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 2121575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2122575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2123c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback.clear(); 21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2126717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (newState == UNINITIALIZED) { 2127671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // return any straggling buffers, e.g. if we got here on an error 2128671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar returnBuffersToCodec(); 2129671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 2130aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // The component is gone, mediaserver's probably back up already 2131aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // but should definitely be back up should we try to instantiate 2132aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // another component.. and the cycle continues. 2133aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags &= ~kFlagSawMediaServerDie; 2134717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2135717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber mState = newState; 21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 21392606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 21402606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang updateBatteryStat(); 21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21435778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() { 21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21485778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 21507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21525778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 21565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21575778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify != NULL) { 21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> msg = info->mNotify; 21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mOwnedByClient = false; 21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexInput) { 21637fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar /* no error, just returning buffers */ 21647fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar msg->setInt32("err", OK); 21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->post(); 21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].clear(); 21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21735778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers( 21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex, const sp<AMessage> &msg) { 21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2177609b815a3131d22da38b2f452faa9f89daad4039Andy Hung uint32_t bufferID; 2178609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 21815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mBufferID == bufferID) { 21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mNotify == NULL); 21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("reply", &info->mNotify)); 21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2189475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mFormat = 2190475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat; 21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].push_back(i); 21925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21935778822d86b0337407514b9372562b86edfa91cdAndreas Huber return i; 21945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21955778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21975778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 21985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21995778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 22005778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 22015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22025778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 22035778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 22045778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset; 22055778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size; 22065778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 22075778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 22085778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 22095778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("offset", &offset)); 22105778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 22115778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 22125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples; 22144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples; 22154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *key; 22164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *iv; 22174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 22184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // We allow the simpler queueInputBuffer API to be used even in 22204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // secure mode, by fabricating a single unencrypted subSample. 22214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::SubSample ss; 22224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (msg->findSize("size", &size)) { 22244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto != NULL) { 22254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfClearData = size; 22264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfEncryptedData = 0; 22274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples = &ss; 22294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples = 1; 22304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber key = NULL; 22314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber iv = NULL; 22324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } else { 22344b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto == NULL) { 22354b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber return -EINVAL; 22364b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22374b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22384b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 22394b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findSize("numSubSamples", &numSubSamples)); 22404b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("key", (void **)&key)); 22414b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("iv", (void **)&iv)); 22424b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22434b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int32_t tmp; 22444b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findInt32("mode", &tmp)); 22454b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22464b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber mode = (CryptoPlugin::Mode)tmp; 22474b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22484b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size = 0; 22494b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber for (size_t i = 0; i < numSubSamples; ++i) { 22504b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfClearData; 22514b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfEncryptedData; 22524b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22534b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22544b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexInput].size()) { 22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 22605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22615778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 22625778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 22635778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22645778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22655778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (offset + size > info->mData->capacity()) { 22665778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 22675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22695778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> reply = info->mNotify; 22705778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->setRange(offset, size); 22715778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt64("timeUs", timeUs); 22725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22735778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_EOS) { 22745778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("eos", true); 22755778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22775778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_CODECCONFIG) { 22785778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("csd", true); 22795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mCrypto != NULL) { 22821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (size > info->mEncryptedData->capacity()) { 22831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -ERANGE; 2284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2285ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 22865b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg; 22875b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 22885b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 2289fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong ssize_t result = mCrypto->decrypt( 22901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (mFlags & kFlagIsSecure) != 0, 22911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber key, 22921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber iv, 22931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mode, 2294c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info->mSharedEncryptedBuffer, 2295c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker offset, 22964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples, 22974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples, 22985b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mData->base(), 22995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg); 23001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 2301fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong if (result < 0) { 2302fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong return result; 2303ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2304ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2305fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong info->mData->setRange(0, result); 2306ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2307ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 23087bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 23097bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 23107bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 23127bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 23132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber reply->setBuffer("buffer", info->mData); 23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber reply->post(); 23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23165b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mNotify = NULL; 23175b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23215778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 23235778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 23245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23255778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t render; 23265778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("render", &render)) { 23275778822d86b0337407514b9372562b86edfa91cdAndreas Huber render = 0; 23285778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23300e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 23325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23335778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexOutput].size()) { 23355778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 23365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23385778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 23395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23405778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 23415778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 23425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23447bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 23457bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 23467bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23477bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 23487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 23497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 235079ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou if (render && info->mData != NULL && info->mData->size() != 0) { 23515778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->setInt32("render", true); 23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2353fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar int64_t timestampNs = 0; 2354fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (msg->findInt64("timestampNs", ×tampNs)) { 2355fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar info->mNotify->setInt64("timestampNs", timestampNs); 2356fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } else { 2357fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // TODO: it seems like we should use the timestamp 2358fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // in the (media)buffer as it potentially came from 2359fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // an input surface, but we did not propagate it prior to 2360fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // API 20. Perhaps check for target SDK version. 2361fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0 2362fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 236347aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar ALOGV("using buffer PTS of %" PRId64, timestampNs); 2364fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar timestampNs *= 1000; 2365fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2366fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif 2367fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2368fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mSoftRenderer != NULL) { 23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer->render( 2371475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mData->data(), info->mData->size(), 2372475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu timestampNs, NULL, info->mFormat); 23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23765778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->post(); 23775778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 23785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 23805778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23825778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 23835778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 23845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23855778822d86b0337407514b9372562b86edfa91cdAndreas Huber List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 23865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23875778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (availBuffers->empty()) { 23885778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EAGAIN; 23895778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index = *availBuffers->begin(); 23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber availBuffers->erase(availBuffers->begin()); 23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 23955778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(!info->mOwnedByClient); 23967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 23977bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23987bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = true; 239903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar 240003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar // set image-data 240103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat != NULL) { 240203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar sp<ABuffer> imageData; 240303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findBuffer("image-data", &imageData)) { 240403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setBuffer("image-data", imageData); 240503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 240603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar int32_t left, top, right, bottom; 240703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) { 240803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setRect("crop-rect", left, top, right, bottom); 240903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 241003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 24117bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 24125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24135778822d86b0337407514b9372562b86edfa91cdAndreas Huber return index; 24145778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 24155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 24167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow( 24171a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian const sp<Surface> &surfaceTextureClient) { 24187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber status_t err; 24197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (mNativeWindow != NULL) { 24217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber err = native_window_api_disconnect( 24227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA); 24237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 24257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ALOGW("native_window_api_disconnect returned an error: %s (%d)", 24267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber strerror(-err), err); 24277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24287541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24297541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow.clear(); 24307541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24317541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24327541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (surfaceTextureClient != NULL) { 24337541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber err = native_window_api_connect( 24347541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA); 24357541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24367541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 24377541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ALOGE("native_window_api_connect returned an error: %s (%d)", 24387541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber strerror(-err), err); 24397541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24407541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber return err; 24417541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24427541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24437541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow = surfaceTextureClient; 24447541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24457541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24467541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber return OK; 24477541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber} 24487541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 2449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() { 2450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) { 2452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_INPUT_AVAILABLE); 2454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2459c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() { 2460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) { 2462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang const sp<ABuffer> &buffer = 2463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mPortBuffers[kPortIndexOutput].itemAt(index).mData; 2464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE); 2466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("offset", buffer->offset()); 2468c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("size", buffer->size()); 2469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2470c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int64_t timeUs; 2471c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2472c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2473c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt64("timeUs", timeUs); 2474c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2475c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t omxFlags; 2476c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 2477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2478c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang uint32_t flags = 0; 2479c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 2480c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_SYNCFRAME; 2481c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2482c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 2483c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_CODECCONFIG; 2484c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2485c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_EOS) { 2486c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_EOS; 2487c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2488c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2489c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("flags", flags); 2490c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2491c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2492c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2493c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2494c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2495749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) { 2496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2498c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_ERROR); 2499c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("err", err); 2500749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setInt32("actionCode", actionCode); 2501749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang 2502749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang if (detail != NULL) { 2503749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setString("detail", detail); 2504749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang } 2505c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2506c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2507c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2508c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2509c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2510c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() { 2511c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2512c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2513c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED); 2514c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("format", mOutputFormat); 2515c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2516c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2517c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2518c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2519c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2520575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() { 2521575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (mActivityNotify == NULL) { 2522575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber return; 2523575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2524575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2525e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang bool isErrorOrOutputChanged = 2526e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang (mFlags & (kFlagStickyError 2527575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber | kFlagOutputBuffersChanged 2528e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang | kFlagOutputFormatChanged)); 2529e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2530e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged 2531575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexInput].empty() 2532575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexOutput].empty()) { 2533e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("input-buffers", 2534e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexInput].size()); 2535e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2536e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged) { 2537e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang // we want consumer to dequeue as many times as it can 2538e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", INT32_MAX); 2539e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } else { 2540e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", 2541e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexOutput].size()); 2542e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } 2543575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify->post(); 2544575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2545575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2546575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 2547575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2548a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 25491d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 2550a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber msg->setMessage("params", params); 2551a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2552a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> response; 2553a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return PostAndAwaitResponse(msg, &response); 2554a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2555a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2556a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 2557a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber mCodec->signalSetParameters(params); 2558a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2559a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return OK; 2560a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2561a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData( 2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const sp<ABuffer> &buffer) { 2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber AString mime; 2565e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber CHECK(mOutputFormat->findString("mime", &mime)); 2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Codec specific data should be SPS and PPS in a single buffer, 2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // each prefixed by a startcode (0x00 0x00 0x00 0x01). 2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // We separate the two and put them into the output format 2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // under the keys "csd-0" and "csd-1". 2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber unsigned csdIndex = 0; 2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *data = buffer->data(); 2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t size = buffer->size(); 2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *nalStart; 2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t nalSize; 2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber sp<ABuffer> csd = new ABuffer(nalSize + 4); 2582e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data(), "\x00\x00\x00\x01", 4); 2583e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data() + 4, nalStart, nalSize); 2584e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2585e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer( 2586a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes AStringPrintf("csd-%u", csdIndex).c_str(), csd); 2587e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2588e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ++csdIndex; 2589e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2590e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2591e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (csdIndex != 2) { 2592e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return ERROR_MALFORMED; 2593e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2594e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 2595e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // For everything else we just stash the codec specific data into 2596e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the output format as a single piece of csd under "csd-0". 2597e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer("csd-0", buffer); 2598e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2599e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2600e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return OK; 2601e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} 2602e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 26032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() { 26042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mState == CONFIGURED && !mBatteryStatNotified) { 26052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier& notifier(BatteryNotifier::getInstance()); 26062606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26072606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mIsVideo) { 26082606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStartVideo(); 26092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else { 26102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStartAudio(); 26112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 26122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26132606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = true; 26142606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else if (mState == UNINITIALIZED && mBatteryStatNotified) { 26152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier& notifier(BatteryNotifier::getInstance()); 26162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26172606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mIsVideo) { 26182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStopVideo(); 26192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else { 26202606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStopAudio(); 26212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 26222606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26232606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = false; 26242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 26252606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 26262606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26275778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 2628