MediaCodec.cpp revision 3d66eb4128aebef31bb0fa44c4d53d6122294a26
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 8267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprotected: 8367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu virtual ~ResourceManagerClient() {} 8467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 8567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuprivate: 8667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu wp<MediaCodec> mMediaCodec; 8767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 8867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient); 8967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu}; 9067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangstruct MediaCodec::BatteryNotifier : public Singleton<BatteryNotifier> { 922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier(); 93d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang virtual ~BatteryNotifier(); 942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStartVideo(); 962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStopVideo(); 972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStartAudio(); 982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang void noteStopAudio(); 99d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang void onBatteryStatServiceDied(); 1002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangprivate: 102d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang struct DeathNotifier : public IBinder::DeathRecipient { 103d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang DeathNotifier() {} 104d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang virtual void binderDied(const wp<IBinder>& /*who*/) { 105d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang BatteryNotifier::getInstance().onBatteryStatServiceDied(); 106d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 107d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang }; 108d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 109d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex mLock; 1102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang int32_t mVideoRefCount; 1112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang int32_t mAudioRefCount; 1122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang sp<IBatteryStats> mBatteryStatService; 113d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<DeathNotifier> mDeathNotifier; 114d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 115d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> getBatteryService_l(); 116d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 117d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang DISALLOW_EVIL_CONSTRUCTORS(BatteryNotifier); 1182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang}; 1192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1202606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangANDROID_SINGLETON_STATIC_INSTANCE(MediaCodec::BatteryNotifier) 1212606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1222606b10d51c2dceb851a2ea63e803aba4134bf00Chong ZhangMediaCodec::BatteryNotifier::BatteryNotifier() : 1232606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount(0), 1242606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount(0) { 125d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 126d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 127d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangsp<IBatteryStats> MediaCodec::BatteryNotifier::getBatteryService_l() { 128d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mBatteryStatService != NULL) { 129d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return mBatteryStatService; 130d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 131d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // get battery service from service manager 1322606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang const sp<IServiceManager> sm(defaultServiceManager()); 1332606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (sm != NULL) { 1342606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang const String16 name("batterystats"); 135d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService = 136d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang interface_cast<IBatteryStats>(sm->getService(name)); 1372606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mBatteryStatService == NULL) { 1382606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGE("batterystats service unavailable!"); 139d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return NULL; 140d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 141d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier = new DeathNotifier(); 142d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (IInterface::asBinder(mBatteryStatService)-> 143d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang linkToDeath(mDeathNotifier) != OK) { 144d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService.clear(); 145d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier.clear(); 146d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return NULL; 1472606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 148d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // notify start now if media already started 149d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount > 0) { 150d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService->noteStartVideo(AID_MEDIA); 151d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 152d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount > 0) { 153d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService->noteStartAudio(AID_MEDIA); 154d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 155d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang } 156d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang return mBatteryStatService; 157d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 158d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 159d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong ZhangMediaCodec::BatteryNotifier::~BatteryNotifier() { 160d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mDeathNotifier != NULL) { 161d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang IInterface::asBinder(mBatteryStatService)-> 162d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang unlinkToDeath(mDeathNotifier); 1632606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1642606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1652606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1662606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartVideo() { 167d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 168d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 169d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount == 0 && batteryService != NULL) { 170d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStartVideo(AID_MEDIA); 1712606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1722606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount++; 1732606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1742606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1752606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopVideo() { 176d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 1772606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mVideoRefCount == 0) { 1782606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGW("BatteryNotifier::noteStop(): video refcount is broken!"); 1792606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang return; 1802606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1812606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mVideoRefCount--; 183d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 184d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mVideoRefCount == 0 && batteryService != NULL) { 185d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStopVideo(AID_MEDIA); 1862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStartAudio() { 190d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 191d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 192d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount == 0 && batteryService != NULL) { 193d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStartAudio(AID_MEDIA); 1942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 1952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount++; 1962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 1972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 1982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::BatteryNotifier::noteStopAudio() { 199d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 2002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mAudioRefCount == 0) { 2012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang ALOGW("BatteryNotifier::noteStop(): audio refcount is broken!"); 2022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang return; 2032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 2052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mAudioRefCount--; 206d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang sp<IBatteryStats> batteryService = getBatteryService_l(); 207d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang if (mAudioRefCount == 0 && batteryService != NULL) { 208d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang batteryService->noteStopAudio(AID_MEDIA); 2092606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 2102606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 211d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 212d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhangvoid MediaCodec::BatteryNotifier::onBatteryStatServiceDied() { 213d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang Mutex::Autolock _l(mLock); 214d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mBatteryStatService.clear(); 215d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang mDeathNotifier.clear(); 216d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // Do not reset mVideoRefCount and mAudioRefCount here. The ref 217d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // counting is independent of the battery service availability. 218d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // We need this if battery service becomes available after media 219d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang // started. 220d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang} 221d7ed649cfeff62680b8edb4cb86ce239116d8c8bChong Zhang 22267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy() { 22367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 22467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 22567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua WuMediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() { 22667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService != NULL) { 22767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu IInterface::asBinder(mService)->unlinkToDeath(this); 22867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 22967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 23067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 23167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::init() { 23267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IServiceManager> sm = defaultServiceManager(); 23367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<IBinder> binder = sm->getService(String16("media.resource_manager")); 23467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService = interface_cast<IResourceManagerService>(binder); 23567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 23667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("Failed to get ResourceManagerService"); 23767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 23867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 23967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (IInterface::asBinder(mService)->linkToDeath(this) != OK) { 24067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService.clear(); 24167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("Failed to linkToDeath to ResourceManagerService."); 24267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 24367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 24467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 24567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 24667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) { 24767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGW("ResourceManagerService died."); 24867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 24967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService.clear(); 25067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 25167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 25267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::addResource( 25367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int pid, 25467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int64_t clientId, 25567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const sp<IResourceManagerClient> client, 25667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const Vector<MediaResource> &resources) { 25767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 25867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 25967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 26067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 26167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService->addResource(pid, clientId, client, resources); 26267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 26367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 26467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) { 26567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 26767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return; 26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mService->removeResource(clientId); 27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wubool MediaCodec::ResourceManagerServiceProxy::reclaimResource( 27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu int callingPid, const Vector<MediaResource> &resources) { 27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Mutex::Autolock _l(mLock); 27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mService == NULL) { 27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return false; 27767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return mService->reclaimResource(callingPid, resources); 27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 2815778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 2825778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByType( 283251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const sp<ALooper> &looper, const char *mime, bool encoder, status_t *err) { 2845778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = new MediaCodec(looper); 2855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 286251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(mime, true /* nameIsType */, encoder); 287251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 288251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 289251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 290251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 2915778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 2945778822d86b0337407514b9372562b86edfa91cdAndreas Hubersp<MediaCodec> MediaCodec::CreateByComponentName( 295251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const sp<ALooper> &looper, const char *name, status_t *err) { 2965778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<MediaCodec> codec = new MediaCodec(looper); 2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung const status_t ret = codec->init(name, false /* nameIsType */, false /* encoder */); 299251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err != NULL) { 300251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung *err = ret; 301251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 302251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return ret == OK ? codec : NULL; // NULL deallocates codec. 3035778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3055778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::MediaCodec(const sp<ALooper> &looper) 3065778822d86b0337407514b9372562b86edfa91cdAndreas Huber : mState(UNINITIALIZED), 3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper(looper), 30892cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar mCodec(NULL), 3097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID(0), 3105778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags(0), 31167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerClient(new ResourceManagerClient(this)), 31267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService(new ResourceManagerServiceProxy()), 313251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError(OK), 3145778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer(NULL), 3152606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified(false), 3162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mIsVideo(false), 31767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoWidth(0), 31867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mVideoHeight(0), 3195778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputTimeoutGeneration(0), 3205778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID(0), 3215778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputTimeoutGeneration(0), 3226507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mDequeueOutputReplyID(0), 3233d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHaveInputSurface(false), 3243d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers(false) { 3255778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3275778822d86b0337407514b9372562b86edfa91cdAndreas HuberMediaCodec::~MediaCodec() { 3285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, UNINITIALIZED); 32967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 3305778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber// static 3335778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::PostAndAwaitResponse( 3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &msg, sp<AMessage> *response) { 3355778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = msg->postAndAwaitResponse(response); 3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (err != OK) { 3385778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3415778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!(*response)->findInt32("err", &err)) { 3425778822d86b0337407514b9372562b86edfa91cdAndreas Huber err = OK; 3435778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 3445778822d86b0337407514b9372562b86edfa91cdAndreas Huber 3455778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 3465778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 3475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 348c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang// static 3493f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarvoid MediaCodec::PostReplyWithError(const sp<AReplyToken> &replyID, int32_t err) { 350c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 351c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->setInt32("err", err); 352c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 353c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 354c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 355dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hungstatus_t MediaCodec::init(const AString &name, bool nameIsType, bool encoder) { 35667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->init(); 35767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 358671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // save init parameters for reset 359671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitName = name; 360671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitNameIsType = nameIsType; 361671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInitIsEncoder = encoder; 362671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Current video decoders do not return from OMX_FillThisBuffer 3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber // quickly, violating the OpenMAX specs, until that is remedied 3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber // we need to invest in an extra looper to free the main event 3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber // queue. 367744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 368bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung if (nameIsType || !strncasecmp(name.c_str(), "omx.", 4)) { 369744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mCodec = new ACodec; 370744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else if (!nameIsType 371bcc1a8299224b35aa2d16cf522d4aa5bcfa1ab60Andy Hung && !strncasecmp(name.c_str(), "android.filter.", 15)) { 372744f5739019d1fd917f981e740b353c3d73fd1a8David Smith mCodec = new MediaFilter; 373744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } else { 374744f5739019d1fd917f981e740b353c3d73fd1a8David Smith return NAME_NOT_FOUND; 375744f5739019d1fd917f981e740b353c3d73fd1a8David Smith } 376744f5739019d1fd917f981e740b353c3d73fd1a8David Smith 37767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu bool secureCodec = false; 378dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung if (nameIsType && !strncasecmp(name.c_str(), "video/", 6)) { 37967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 3806f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } else { 3816f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen AString tmp = name; 3826f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (tmp.endsWith(".secure")) { 38367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu secureCodec = true; 3846f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen tmp.erase(tmp.size() - 7, 7); 3856f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 38660b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<IMediaCodecList> mcl = MediaCodecList::getInstance(); 3876f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen ssize_t codecIdx = mcl->findCodecByName(tmp.c_str()); 3886f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen if (codecIdx >= 0) { 38960b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar const sp<MediaCodecInfo> info = mcl->getCodecInfo(codecIdx); 39060b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar Vector<AString> mimes; 39160b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar info->getSupportedMimes(&mimes); 39260b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar for (size_t i = 0; i < mimes.size(); i++) { 39360b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar if (mimes[i].startsWith("video/")) { 39467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mIsVideo = true; 39560b1c0e79d12a1c70758bc8d060156924635f8baLajos Molnar break; 3966f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 3976f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 3986f9439efd2a6004b588605f6a9d4af20c98e8e80Marco Nelissen } 3995778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 40167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 40267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // video codec needs dedicated looper 4035778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mCodecLooper == NULL) { 4045778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper = new ALooper; 4055778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->setName("CodecLooper"); 4065778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO); 4075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4095778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodecLooper->registerHandler(mCodec); 4105778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 4115778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(mCodec); 4125778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber mLooper->registerHandler(this); 4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4161d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar mCodec->setNotificationMessage(new AMessage(kWhatCodecNotify, this)); 4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4181d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatInit, this); 4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setString("name", name); 4205778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("nameIsType", nameIsType); 4215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4225778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 4235778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("encoder", encoder); 4245778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 42667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 42767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 42867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = secureCodec ? kResourceSecureCodec : kResourceNonSecureCodec; 42967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(type), 1)); 43067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 43167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 43267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 43367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 43467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 43567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 43667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 43767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 43867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 43967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 44067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 44167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 44267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 44367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 44467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 4455778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 4465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 447c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangstatus_t MediaCodec::setCallback(const sp<AMessage> &callback) { 4481d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetCallback, this); 449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("callback", callback); 450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response; 452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang return PostAndAwaitResponse(msg, &response); 453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 4555778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::configure( 4565778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<AMessage> &format, 4571a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian const sp<Surface> &nativeWindow, 4581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const sp<ICrypto> &crypto, 4595778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags) { 4601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatConfigure, this); 4615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 46267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 46367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("width", &mVideoWidth); 46467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu format->findInt32("height", &mVideoHeight); 46567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 46667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 4675778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setMessage("format", format); 4685778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 4695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 4705778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nativeWindow != NULL) { 4711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber msg->setObject( 4721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber "native-window", 4731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber new NativeWindowWrapper(nativeWindow)); 4741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 4751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 4761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (crypto != NULL) { 4771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber msg->setPointer("crypto", crypto.get()); 4785778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 4795778822d86b0337407514b9372562b86edfa91cdAndreas Huber 48067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // save msg for reset 48167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mConfigureMsg = msg; 482f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 48367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 48467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 48567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = (mFlags & kFlagIsSecure) ? 48667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu kResourceSecureCodec : kResourceNonSecureCodec; 48767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(type), 1)); 48867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 48967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 49067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1)); 49167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 49267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 49367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 49467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 49567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 49667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 49767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 498f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang 49967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 50067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 50167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK && err != INVALID_OPERATION) { 50267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // MediaCodec now set state to UNINITIALIZED upon any fatal error. 50367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // To maintain backward-compatibility, do a reset() to put codec 50467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // back into INITIALIZED state. 50567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // But don't reset if the err is INVALID_OPERATION, which means 50667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the configure failure is due to wrong state. 50767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 50867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("configure failed with err 0x%08x, resetting...", err); 50967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu reset(); 51067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 51167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 51267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 51367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 514f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang } 515f64b36deccd473b545dbed22c2feb11fc49157e5Chong Zhang return err; 5165778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::createInputSurface( 5197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<IGraphicBufferProducer>* bufferProducer) { 5201d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatCreateInputSurface, this); 5217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 5227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 5237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = PostAndAwaitResponse(msg, &response); 5247cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (err == NO_ERROR) { 5257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // unwrap the sp<IGraphicBufferProducer> 5267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 5277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden bool found = response->findObject("input-surface", &obj); 5287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(found); 5297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<BufferProducerWrapper> wrapper( 5307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden static_cast<BufferProducerWrapper*>(obj.get())); 5317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden *bufferProducer = wrapper->getBufferProducer(); 5327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 5337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden ALOGW("createInputSurface failed, err=%d", err); 5347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 5357cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return err; 5367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 5377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 53867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuuint64_t MediaCodec::getGraphicBufferSize() { 53967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mIsVideo) { 54067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return 0; 54167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 54267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 54367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu uint64_t size = 0; 54467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size_t portNum = sizeof(mPortBuffers) / sizeof((mPortBuffers)[0]); 54567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (size_t i = 0; i < portNum; ++i) { 54667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // TODO: this is just an estimation, we should get the real buffer size from ACodec. 54767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu size += mPortBuffers[i].size() * mVideoWidth * mVideoHeight * 3 / 2; 54867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 54967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return size; 55067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 55167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 55267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wuvoid MediaCodec::addResource(const char *type, uint64_t value) { 55367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 55467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(type), value)); 55567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->addResource( 55667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu getCallingPid(), getId(mResourceManagerClient), mResourceManagerClient, resources); 55767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu} 55867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 5595778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::start() { 5601d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStart, this); 5615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 56267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu status_t err; 56367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu Vector<MediaResource> resources; 56467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu const char *type = (mFlags & kFlagIsSecure) ? 56567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu kResourceSecureCodec : kResourceNonSecureCodec; 56667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(type), 1)); 56767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't know the buffer size at this point, but it's fine to use 1 because 56867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // the reclaimResource call doesn't consider the requester's buffer size for now. 56967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resources.push_back(MediaResource(String8(kResourceGraphicMemory), 1)); 57067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu for (int i = 0; i <= kMaxRetry; ++i) { 57167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (i > 0) { 57267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Don't try to reclaim resource for the first time. 57367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!mResourceManagerService->reclaimResource(getCallingPid(), resources)) { 57467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 57567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 57667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu // Recover codec from previous error before retry start. 57767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = reset(); 57867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 57967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to reset codec"); 58067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 58167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 58267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 58367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(mConfigureMsg, &response); 58467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (err != OK) { 58567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu ALOGE("retrying start: failed to configure codec"); 58667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 58767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 58867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 58967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 59067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu sp<AMessage> response; 59167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu err = PostAndAwaitResponse(msg, &response); 59267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (!isResourceError(err)) { 59367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu break; 59467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 59667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu return err; 5975778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 5985778822d86b0337407514b9372562b86edfa91cdAndreas Huber 5995778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::stop() { 6001d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatStop, this); 6015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6025778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 6035778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 6045778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 606c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huberstatus_t MediaCodec::release() { 6071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRelease, this); 608c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 609c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response; 610c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber return PostAndAwaitResponse(msg, &response); 611c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber} 612c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 613671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnarstatus_t MediaCodec::reset() { 614671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar /* When external-facing MediaCodec object is created, 615671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar it is already initialized. Thus, reset is essentially 616671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar release() followed by init(), plus clearing the state */ 617671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 618671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar status_t err = release(); 619671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 620671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // unregister handlers 621671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodec != NULL) { 622671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (mCodecLooper != NULL) { 623671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodecLooper->unregisterHandler(mCodec->id()); 624671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } else { 625671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(mCodec->id()); 626671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 627671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mCodec = NULL; 628671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 629671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mLooper->unregisterHandler(id()); 630671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 631671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mFlags = 0; // clear all flags 632251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 633671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 634671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // reset state not reset by setState(UNINITIALIZED) 635671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mReplyID = 0; 636671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputReplyID = 0; 637671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputReplyID = 0; 638671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueInputTimeoutGeneration = 0; 639671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mDequeueOutputTimeoutGeneration = 0; 640671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mHaveInputSurface = false; 641671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 642671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar if (err == OK) { 643dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung err = init(mInitName, mInitNameIsType, mInitIsEncoder); 644671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar } 645671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar return err; 646671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar} 647671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 6485778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::queueInputBuffer( 6495778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index, 6505778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset, 6515778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size, 6525778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t presentationTimeUs, 6535b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 6545b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 6555b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 6565b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 6575b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 6585b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 6591d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 6605778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 6615778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("offset", offset); 6625778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("size", size); 6635778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 6645778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("flags", flags); 6655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 6665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6675778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 6685778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 6695778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 6705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 6714b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huberstatus_t MediaCodec::queueSecureInputBuffer( 6724b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t index, 6734b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t offset, 6744b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples, 6754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples, 6764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t key[16], 6774b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t iv[16], 6784b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode, 6794b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int64_t presentationTimeUs, 6805b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber uint32_t flags, 6815b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 6825b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber if (errorDetailMsg != NULL) { 6835b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->clear(); 6845b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 6855b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 6861d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 6874b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("index", index); 6884b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("offset", offset); 6894b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("subSamples", (void *)subSamples); 6904b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setSize("numSubSamples", numSubSamples); 6914b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("key", (void *)key); 6924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setPointer("iv", (void *)iv); 6934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("mode", mode); 6944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt64("timeUs", presentationTimeUs); 6954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber msg->setInt32("flags", flags); 6965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber msg->setPointer("errorDetailMsg", errorDetailMsg); 6974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 6984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber sp<AMessage> response; 6995b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber status_t err = PostAndAwaitResponse(msg, &response); 7005b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 7015b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber return err; 7024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber} 7034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 7045778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) { 7051d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueInputBuffer, this); 7065778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7085778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7095778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7105778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7115778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7125778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7145778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7165778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7175778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7195778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::dequeueOutputBuffer( 7205778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *index, 7215778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *offset, 7225778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t *size, 7235778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t *presentationTimeUs, 7245778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t *flags, 7255778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs) { 7261d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatDequeueOutputBuffer, this); 7275778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt64("timeoutUs", timeoutUs); 7285778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7295778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7305778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7315778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7325778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7335778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7355778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("index", index)); 7365778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("offset", offset)); 7375778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findSize("size", size)); 7385778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt64("timeUs", presentationTimeUs)); 7395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findInt32("flags", (int32_t *)flags)); 7405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7415778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7425778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7445778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index) { 7451d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 7465778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7475778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("render", true); 7485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7495778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7505778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7515778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 753fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnarstatus_t MediaCodec::renderOutputBufferAndRelease(size_t index, int64_t timestampNs) { 7541d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 755fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setSize("index", index); 756fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt32("render", true); 757fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar msg->setInt64("timestampNs", timestampNs); 758fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 759fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar sp<AMessage> response; 760fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar return PostAndAwaitResponse(msg, &response); 761fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar} 762fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 7635778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::releaseOutputBuffer(size_t index) { 7641d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatReleaseOutputBuffer, this); 7655778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setSize("index", index); 7665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7675778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7685778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 7695778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7717cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFaddenstatus_t MediaCodec::signalEndOfInputStream() { 7721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSignalEndOfInputStream, this); 7737cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 7747cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response; 7757cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden return PostAndAwaitResponse(msg, &response); 7767cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden} 7777cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 7785778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputFormat(sp<AMessage> *format) const { 7791d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetOutputFormat, this); 7805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7815778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 7825778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err; 7835778822d86b0337407514b9372562b86edfa91cdAndreas Huber if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 7845778822d86b0337407514b9372562b86edfa91cdAndreas Huber return err; 7855778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 7865778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7875778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(response->findMessage("format", format)); 7885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 7895778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 7905778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 7915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 792e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnarstatus_t MediaCodec::getInputFormat(sp<AMessage> *format) const { 7931d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetInputFormat, this); 794e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 795e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> response; 796e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar status_t err; 797e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 798e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return err; 799e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar } 800e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 801e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(response->findMessage("format", format)); 802e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 803e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar return OK; 804e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar} 805e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 806717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjostatus_t MediaCodec::getName(AString *name) const { 8071d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetName, this); 808717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 809717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response; 810717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo status_t err; 811717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if ((err = PostAndAwaitResponse(msg, &response)) != OK) { 812717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return err; 813717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 814717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 815717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(response->findString("name", name)); 816717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 817717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo return OK; 818717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo} 819717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 820e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnarstatus_t MediaCodec::getWidevineLegacyBuffers(Vector<sp<ABuffer> > *buffers) const { 821e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 822e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("portIndex", kPortIndexInput); 823e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setPointer("buffers", buffers); 824e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->setInt32("widevine", true); 825e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 826e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar sp<AMessage> response; 827e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar return PostAndAwaitResponse(msg, &response); 828e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar} 829e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar 8305778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getInputBuffers(Vector<sp<ABuffer> > *buffers) const { 8311d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8325778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexInput); 8335778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8355778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8365778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8375778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8395778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::getOutputBuffers(Vector<sp<ABuffer> > *buffers) const { 8401d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatGetBuffers, this); 8415778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setInt32("portIndex", kPortIndexOutput); 8425778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->setPointer("buffers", buffers); 8435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8445778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 8455778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 8465778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 8475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 8487bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputBuffer(size_t index, sp<ABuffer> *buffer) { 8497bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 8507bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, buffer, &format); 8517bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8527bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8537bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getOutputFormat(size_t index, sp<AMessage> *format) { 8547bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> buffer; 8557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexOutput, index, &buffer, format); 8567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8577bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8587bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getInputBuffer(size_t index, sp<ABuffer> *buffer) { 8597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<AMessage> format; 8607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return getBufferAndFormat(kPortIndexInput, index, buffer, &format); 8617bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnarbool MediaCodec::isExecuting() const { 8640e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar return mState == STARTED || mState == FLUSHED; 8650e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar} 8660e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar 8677bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnarstatus_t MediaCodec::getBufferAndFormat( 8687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar size_t portIndex, size_t index, 8697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar sp<ABuffer> *buffer, sp<AMessage> *format) { 8707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // use mutex instead of a context switch 8717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8727bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar buffer->clear(); 8737bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar format->clear(); 8740e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 8757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return INVALID_OPERATION; 8767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 8777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8787bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we do not want mPortBuffers to change during this section 8797bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // we also don't want mOwnedByClient to change during this 8807bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 8817bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 8827bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar if (index < buffers->size()) { 8837bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo &info = buffers->itemAt(index); 8847bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar if (info.mOwnedByClient) { 8850837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar // by the time buffers array is initialized, crypto is set 8860837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar if (portIndex == kPortIndexInput && mCrypto != NULL) { 8870837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar *buffer = info.mEncryptedData; 8880837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar } else { 8890837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar *buffer = info.mData; 8900837d0ac1b572923a27f1b0b742960fc64a6b162Lajos Molnar } 8917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar *format = info.mFormat; 8927bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 8937bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 8947bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar return OK; 8957bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar} 8967bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 8975778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::flush() { 8981d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatFlush, this); 8995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9005778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response; 9015778822d86b0337407514b9372562b86edfa91cdAndreas Huber return PostAndAwaitResponse(msg, &response); 9025778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 904496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huberstatus_t MediaCodec::requestIDRFrame() { 9051d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar (new AMessage(kWhatRequestIDRFrame, this))->post(); 906496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 907496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber return OK; 908496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber} 909496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 910575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::requestActivityNotification(const sp<AMessage> ¬ify) { 9111d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, this); 912575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->setMessage("notify", notify); 913575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber msg->post(); 914575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 915575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 9165778822d86b0337407514b9372562b86edfa91cdAndreas Huber//////////////////////////////////////////////////////////////////////////////// 9175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9185778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::cancelPendingDequeueOperations() { 9195778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueInputPending) { 920c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION); 9215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9225778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 9235778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 9245778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 9255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9275778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mFlags & kFlagDequeueOutputPending) { 928c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION); 9295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9305778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 9315778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 9325778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 9335778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9345778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9363f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 9370e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 9385778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueInputPending))) { 939c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 9405778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 941251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 942251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 943251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung return true; 9445778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9465778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 9475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9485778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 9495778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 9505778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 9515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9535778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 9545778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 9555778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 9565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9575778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 9585778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 9595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9603f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnarbool MediaCodec::handleDequeueOutputBuffer(const sp<AReplyToken> &replyID, bool newRequest) { 9615778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 9625778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting() || (mFlags & kFlagIsAsync) 9645778822d86b0337407514b9372562b86edfa91cdAndreas Huber || (newRequest && (mFlags & kFlagDequeueOutputPending))) { 9655778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INVALID_OPERATION); 966251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 967251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung response->setInt32("err", getStickyError()); 9685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputBuffersChanged) { 9695778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INFO_OUTPUT_BUFFERS_CHANGED); 9705778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 9715778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else if (mFlags & kFlagOutputFormatChanged) { 9725778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("err", INFO_FORMAT_CHANGED); 9735778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 9745778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 9755778822d86b0337407514b9372562b86edfa91cdAndreas Huber ssize_t index = dequeuePortBuffer(kPortIndexOutput); 9765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9775778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index < 0) { 9785778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(index, -EAGAIN); 9795778822d86b0337407514b9372562b86edfa91cdAndreas Huber return false; 9805778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 9815778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9825778822d86b0337407514b9372562b86edfa91cdAndreas Huber const sp<ABuffer> &buffer = 9835778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[kPortIndexOutput].itemAt(index).mData; 9845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9855778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("index", index); 9865778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("offset", buffer->offset()); 9875778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setSize("size", buffer->size()); 9885778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9895778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 9905778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 9915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9925778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt64("timeUs", timeUs); 9935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9945778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 9955778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 9965778822d86b0337407514b9372562b86edfa91cdAndreas Huber 9975778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags = 0; 9985778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 9995778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_SYNCFRAME; 10005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10015778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 10025778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_CODECCONFIG; 10035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10045778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (omxFlags & OMX_BUFFERFLAG_EOS) { 10055778822d86b0337407514b9372562b86edfa91cdAndreas Huber flags |= BUFFER_FLAG_EOS; 10065778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10085778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->setInt32("flags", flags); 10095778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10105778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10115778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 10125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10135778822d86b0337407514b9372562b86edfa91cdAndreas Huber return true; 10145778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 10155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10165778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::onMessageReceived(const sp<AMessage> &msg) { 10175778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (msg->what()) { 10185778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatCodecNotify: 10195778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10205778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t what; 10215778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("what", &what)); 10225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10235778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (what) { 102492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatError: 10255778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1026251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung int32_t err, actionCode; 1027251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("err", &err)); 1028251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung CHECK(msg->findInt32("actionCode", &actionCode)); 10295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10309e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen ALOGE("Codec reported err %#x, actionCode %d, while in state %d", 10319e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen err, actionCode, mState); 1032251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (err == DEAD_OBJECT) { 1033aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags |= kFlagSawMediaServerDie; 103452dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 1035aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1036aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 10375530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia bool sendErrorResponse = true; 10385778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10395778822d86b0337407514b9372562b86edfa91cdAndreas Huber switch (mState) { 10405778822d86b0337407514b9372562b86edfa91cdAndreas Huber case INITIALIZING: 10415778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10425778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(UNINITIALIZED); 10435778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10445778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10455778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10465778822d86b0337407514b9372562b86edfa91cdAndreas Huber case CONFIGURING: 10475778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1048c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1049c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : INITIALIZED); 10505778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10535778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTING: 10545778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1055c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia setState(actionCode == ACTION_CODE_FATAL ? 1056c22c695660ed9edaba0d4cd7c0ab3a794216fe80Wei Jia UNINITIALIZED : CONFIGURED); 10575778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10585778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10605778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STOPPING: 1061c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case RELEASING: 10625778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10635778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Ignore the error, assuming we'll still get 10645778822d86b0337407514b9372562b86edfa91cdAndreas Huber // the shutdown complete notification. 10655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10665530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 106703ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 1068aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 106903ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // MediaServer died, there definitely won't 107003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // be a shutdown complete notification after 107103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // all. 107203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber 107303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // note that we're directly going from 107403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // STOPPING->UNINITIALIZED, instead of the 107503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // usual STOPPING->INITIALIZED state. 107603ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber setState(UNINITIALIZED); 10776e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (mState == RELEASING) { 10786e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 10796e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 108003ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber (new AMessage)->postReply(mReplyID); 108103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber } 10825778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10835778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10855778822d86b0337407514b9372562b86edfa91cdAndreas Huber case FLUSHING: 10865778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10879e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen if (actionCode == ACTION_CODE_FATAL) { 10889e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState(UNINITIALIZED); 10899e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } else { 10909e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen setState( 10919e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen (mFlags & kFlagIsAsync) ? FLUSHED : STARTED); 10929e2b7918eb5621b24bd54c922f630da45339de77Marco Nelissen } 10935778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 10945778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 10955778822d86b0337407514b9372562b86edfa91cdAndreas Huber 10960e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar case FLUSHED: 10975778822d86b0337407514b9372562b86edfa91cdAndreas Huber case STARTED: 10985778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 10995530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1101251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1102575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 11035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11045778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 1105c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1106c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1107251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1108251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1109251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1110251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1111251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1112251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1113251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1114251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1115251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1116251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1117251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1118c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 11195778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11225778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 11235778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11245530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia sendErrorResponse = false; 11255778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1126251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1127575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1128c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1129251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung // actionCode in an uninitialized state is always fatal. 1130251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (mState == UNINITIALIZED) { 1131251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung actionCode = ACTION_CODE_FATAL; 1132251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1133c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1134251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung onError(err, actionCode); 1135251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } 1136251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung switch (actionCode) { 1137251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_TRANSIENT: 1138251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1139251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung case ACTION_CODE_RECOVERABLE: 1140251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(INITIALIZED); 1141251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1142251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung default: 1143251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setState(UNINITIALIZED); 1144251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 1145c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 11465778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11485778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11505530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (sendErrorResponse) { 1151251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(mReplyID, err); 11525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11535778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 115692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentAllocated: 11575778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11585778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, INITIALIZING); 11595778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZED); 116052dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags |= kFlagIsComponentAllocated; 11615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1162717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->findString("componentName", &mComponentName)); 11635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1164717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.startsWith("OMX.google.")) { 11653a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 11665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 11673a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags &= ~kFlagUsesSoftwareRenderer; 11685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 117067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu String8 resourceType; 1171717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.endsWith(".secure")) { 11721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags |= kFlagIsSecure; 117367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resourceType = String8(kResourceSecureCodec); 11741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 11751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFlags &= ~kFlagIsSecure; 117667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu resourceType = String8(kResourceNonSecureCodec); 11771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 117867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu addResource(resourceType, 1); 11791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 11805778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 11815778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 11825778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 11835778822d86b0337407514b9372562b86edfa91cdAndreas Huber 118492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatComponentConfigured: 11855778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 11865778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK_EQ(mState, CONFIGURING); 11875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 11886507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden // reset input surface flag 11896507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = false; 11906507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 1191e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("input-format", &mInputFormat)); 1192e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar CHECK(msg->findMessage("output-format", &mOutputFormat)); 1193e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 11943a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar int32_t usingSwRenderer; 11953a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar if (mOutputFormat->findInt32("using-sw-renderer", &usingSwRenderer) 11963a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar && usingSwRenderer) { 11973a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar mFlags |= kFlagUsesSoftwareRenderer; 11983a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar } 11992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang setState(CONFIGURED); 12005778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 12015778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 12025778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 120492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatInputSurfaceCreated: 12057cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 120692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to initiateCreateInputSurface() 12077cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err = NO_ERROR; 12087cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response = new AMessage(); 12097cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (!msg->findInt32("err", &err)) { 12107cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<RefBase> obj; 12117cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden msg->findObject("input-surface", &obj); 12127cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(obj != NULL); 12137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setObject("input-surface", obj); 12146507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden mHaveInputSurface = true; 12157cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } else { 12167cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 12177cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12187cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 12197cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 12207cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12217cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 122292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatSignaledInputEOS: 12237cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 122492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar // response to signalEndOfInputStream() 12257cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden sp<AMessage> response = new AMessage(); 12267cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden status_t err; 12277cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (msg->findInt32("err", &err)) { 12287cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->setInt32("err", err); 12297cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12307cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden response->postReply(mReplyID); 12317cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 12327cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 12337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 12347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 123592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatBuffersAllocated: 12365778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 12377bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 12385778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 12395778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 12405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12415778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("%s buffers allocated", 12425778822d86b0337407514b9372562b86edfa91cdAndreas Huber portIndex == kPortIndexInput ? "input" : "output"); 12435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12445778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput 12455778822d86b0337407514b9372562b86edfa91cdAndreas Huber || portIndex == kPortIndexOutput); 12465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12475778822d86b0337407514b9372562b86edfa91cdAndreas Huber mPortBuffers[portIndex].clear(); 12485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12495778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 12505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1251eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber sp<RefBase> obj; 1252eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber CHECK(msg->findObject("portDesc", &obj)); 1253eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber 125492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar sp<CodecBase::PortDescription> portDesc = 125592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar static_cast<CodecBase::PortDescription *>(obj.get()); 12565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1257eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber size_t numBuffers = portDesc->countBuffers(); 12585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1259c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker size_t totalSize = 0; 1260c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker for (size_t i = 0; i < numBuffers; ++i) { 1261c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (portIndex == kPortIndexInput && mCrypto != NULL) { 1262c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker totalSize += portDesc->bufferAt(i)->capacity(); 1263c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1264c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1265c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1266c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker if (totalSize) { 1267c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker mDealer = new MemoryDealer(totalSize, "MediaCodec"); 1268c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 1269c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 1270eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber for (size_t i = 0; i < numBuffers; ++i) { 12715778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo info; 1272eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mBufferID = portDesc->bufferIDAt(i); 12735778822d86b0337407514b9372562b86edfa91cdAndreas Huber info.mOwnedByClient = false; 1274eb61431af13741aa8b7e57a39f69bba5a6c190dcAndreas Huber info.mData = portDesc->bufferAt(i); 12755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (portIndex == kPortIndexInput && mCrypto != NULL) { 1277c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sp<IMemory> mem = mDealer->allocate(info.mData->capacity()); 1278ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber info.mEncryptedData = 1279c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker new ABuffer(mem->pointer(), info.mData->capacity()); 1280c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info.mSharedEncryptedBuffer = mem; 1281ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 1282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 12835778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffers->push_back(info); 12845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 12855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 12865778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexOutput) { 12875778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState == STARTING) { 12885778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We're always allocating output buffers after 12895778822d86b0337407514b9372562b86edfa91cdAndreas Huber // allocating input buffers, so this is a good 12905778822d86b0337407514b9372562b86edfa91cdAndreas Huber // indication that now all buffers are allocated. 129167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu if (mIsVideo) { 129267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu addResource(kResourceGraphicMemory, getGraphicBufferSize()); 129367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu } 12945778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTED); 12955778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 12965778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 12975778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagOutputBuffersChanged; 1298575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 12995778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13015778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13025778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 130492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatOutputFormatChanged: 13055778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13065778822d86b0337407514b9372562b86edfa91cdAndreas Huber ALOGV("codec output format changed"); 13075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1308475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mSoftRenderer == NULL && 1309475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mNativeWindow != NULL && 13103a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar (mFlags & kFlagUsesSoftwareRenderer)) { 13115778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString mime; 13125778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("mime", &mime)); 13135778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1314475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (mime.startsWithIgnoreCase("video/")) { 1315475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mSoftRenderer = new SoftwareRenderer(mNativeWindow); 13165778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13175778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13195778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat = msg; 1320e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1321e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagIsEncoder) { 1322e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Before we announce the format change we should 1323e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // collect codec specific data and amend the output 1324e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format as necessary. 1325e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagGatherCodecSpecificData; 1326c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagIsAsync) { 1327c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1328e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 1329e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagOutputFormatChanged; 1330e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber postActivityNotificationIfPossible(); 1331e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 13322514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 13332514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker // Notify mCrypto of video resolution changes 13342514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker if (mCrypto != NULL) { 13358140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar int32_t left, top, right, bottom, width, height; 13368140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar if (mOutputFormat->findRect("crop", &left, &top, &right, &bottom)) { 13378140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(right - left + 1, bottom - top + 1); 13388140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } else if (mOutputFormat->findInt32("width", &width) 13398140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar && mOutputFormat->findInt32("height", &height)) { 13408140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar mCrypto->notifyResolution(width, height); 13418140a2b7ef0650e8cce6be16efcbfce56d0ed1e4Lajos Molnar } 13422514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 13432514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 13445778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13455778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13465778822d86b0337407514b9372562b86edfa91cdAndreas Huber 134792cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFillThisBuffer: 13485778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 13495778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexInput, msg); 13505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1351c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1352c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1353c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 13545778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 13555778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 13565778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (!mCSD.empty()) { 13598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ssize_t index = dequeuePortBuffer(kPortIndexInput); 13608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK_GE(index, 0); 13618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // If codec specific data had been specified as 13638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // part of the format in the call to configure and 13648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // if there's more csd left, we submit it here 13658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // clients only get access to input buffers once 13668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber // this data has been exhausted. 13678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber status_t err = queueCSDInputBuffer(index); 13698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 13708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (err != OK) { 13718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ALOGE("queueCSDInputBuffer failed w/ error %d", 13728ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber err); 13738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1374251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung setStickyError(err); 1375575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1376575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 13778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber cancelPendingDequeueOperations(); 13788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 13798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 13808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 13818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 1382c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 13836e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (!mHaveInputSurface) { 13843d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mState == FLUSHED) { 13853d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = true; 13863d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } else { 13873d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 13883d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 13896e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1390c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueInputPending) { 13915778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueInputBuffer(mDequeueInputReplyID)); 13925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 13935778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueInputTimeoutGeneration; 13945778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 13955778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 1396575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1397575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 13985778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 13995778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 140292cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatDrainThisBuffer: 14035778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14045778822d86b0337407514b9372562b86edfa91cdAndreas Huber /* size_t index = */updateBuffers(kPortIndexOutput, msg); 14055778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1406c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == FLUSHING 1407c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == STOPPING 1408c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber || mState == RELEASING) { 14095778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 14105778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14132d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber sp<ABuffer> buffer; 14142d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber CHECK(msg->findBuffer("buffer", &buffer)); 14155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14165778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t omxFlags; 14175778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", &omxFlags)); 14185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14195778822d86b0337407514b9372562b86edfa91cdAndreas Huber buffer->meta()->setInt32("omxFlags", omxFlags); 14205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1421e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (mFlags & kFlagGatherCodecSpecificData) { 1422e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // This is the very first output buffer after a 1423e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // format change was signalled, it'll either contain 1424e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the one piece of codec specific data we can expect 1425e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // or there won't be codec specific data. 1426e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 1427e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber status_t err = 1428e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber amendOutputFormatWithCodecSpecificData(buffer); 1429e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1430e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (err != OK) { 1431e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ALOGE("Codec spit out malformed codec " 1432e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber "specific data!"); 1433e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1434e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1435e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1436e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 1437c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1438c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputFormatChanged(); 1439c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1440c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagOutputFormatChanged; 1441c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1442e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 1443e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 1444c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1445c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang onOutputBufferAvailable(); 1446c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else if (mFlags & kFlagDequeueOutputPending) { 14475778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(handleDequeueOutputBuffer(mDequeueOutputReplyID)); 14485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14495778822d86b0337407514b9372562b86edfa91cdAndreas Huber ++mDequeueOutputTimeoutGeneration; 14505778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 14515778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 1452575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } else { 1453575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 14545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 1455575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 14565778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 145992cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatEOS: 14605778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14615778822d86b0337407514b9372562b86edfa91cdAndreas Huber // We already notify the client of this by using the 14625778822d86b0337407514b9372562b86edfa91cdAndreas Huber // corresponding flag in "onOutputBufferReady". 14635778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14645778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 146692cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatShutdownCompleted: 14675778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1468c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber if (mState == STOPPING) { 1469c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(INITIALIZED); 1470c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } else { 1471c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK_EQ(mState, RELEASING); 1472c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber setState(UNINITIALIZED); 14736e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 1474c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 147552dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan mFlags &= ~kFlagIsComponentAllocated; 14765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 147767e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu mResourceManagerService->removeResource(getId(mResourceManagerClient)); 147867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu 14795778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 14805778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 14815778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 14825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 148392cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar case CodecBase::kWhatFlushCompleted: 14845778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 14855530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia if (mState != FLUSHING) { 14865530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia ALOGW("received FlushCompleted message in state %d", 14875530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia mState); 14885530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia break; 14895530f7a7f9dff5280be84f2675b3be081beb5540Wei Jia } 14905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14910e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mFlags & kFlagIsAsync) { 14920e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(FLUSHED); 14930e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else { 14940e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar setState(STARTED); 14950e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 14960e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } 14975778822d86b0337407514b9372562b86edfa91cdAndreas Huber 14985778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(mReplyID); 14995778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15005778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15015778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15025778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 15035778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 15045778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15055778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15065778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15085778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatInit: 15095778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15103f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 15115778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 15125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != UNINITIALIZED) { 1514c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 15155778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15165778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15175778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15185778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 15195778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(INITIALIZING); 15205778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15215778822d86b0337407514b9372562b86edfa91cdAndreas Huber AString name; 15225778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findString("name", &name)); 15235778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15245778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t nameIsType; 15255778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t encoder = false; 15260db280176bd3277e3256252d063f3712b1905ba9Andreas Huber CHECK(msg->findInt32("nameIsType", &nameIsType)); 15270db280176bd3277e3256252d063f3712b1905ba9Andreas Huber if (nameIsType) { 15285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("encoder", &encoder)); 15295778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15315778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format = new AMessage; 15325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15335778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (nameIsType) { 15345778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("mime", name.c_str()); 15355778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", encoder); 15365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } else { 15375778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setString("componentName", name.c_str()); 15385778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15405778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateAllocateComponent(format); 15415778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1544c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang case kWhatSetCallback: 1545c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang { 15463f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1547c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->senderAwaitsResponse(&replyID)); 1548c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1549c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mState == UNINITIALIZED 1550c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang || mState == INITIALIZING 15510e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar || isExecuting()) { 15520e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // callback can't be set after codec is executing, 1553c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // or before it's initialized (as the callback 1554c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang // will be cleared when it goes to INITIALIZED) 1555c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1556c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1557c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1558c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1559c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> callback; 1560c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(msg->findMessage("callback", &callback)); 1561c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1562c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback = callback; 1563c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1564c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 1565c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGI("MediaCodec will operate in async mode"); 1566c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags |= kFlagIsAsync; 1567c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } else { 1568c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 1569c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1570c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 1571c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> response = new AMessage; 1572c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang response->postReply(replyID); 1573c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1574c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1575c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 15765778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatConfigure: 15775778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 15783f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 15795778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 15805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15815778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mState != INITIALIZED) { 1582c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 15835778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 15845778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15855778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15865778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<RefBase> obj; 15875778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findObject("native-window", &obj)) { 15885778822d86b0337407514b9372562b86edfa91cdAndreas Huber obj.clear(); 15895778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 15905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15915778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> format; 15925778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("format", &format)); 15935778822d86b0337407514b9372562b86edfa91cdAndreas Huber 15945778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (obj != NULL) { 15955778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setObject("native-window", obj); 15961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 15977541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber status_t err = setNativeWindow( 15987541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber static_cast<NativeWindowWrapper *>(obj.get()) 15997541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ->getSurfaceTextureClient()); 16007541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 16017541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 1602c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 16037541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber break; 16041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 16051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 16067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setNativeWindow(NULL); 16071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 16081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mReplyID = replyID; 16107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setState(CONFIGURING); 16117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 16121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber void *crypto; 16131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (!msg->findPointer("crypto", &crypto)) { 16141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber crypto = NULL; 16155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto = static_cast<ICrypto *>(crypto); 16181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 16195778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 16205778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 16215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16225778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & CONFIGURE_FLAG_ENCODE) { 16235778822d86b0337407514b9372562b86edfa91cdAndreas Huber format->setInt32("encoder", true); 1624e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags |= kFlagIsEncoder; 16255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16278ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber extractCSD(format); 16288ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 16295778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateConfigureComponent(format); 16305778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16315778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16337cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatCreateInputSurface: 16347cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 16353f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16367cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 16377cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16387cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden // Must be configured, but can't have been started yet. 16397cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden if (mState != CONFIGURED) { 1640c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16417cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 16427cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 16437cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16447cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 16457cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->initiateCreateInputSurface(); 16467cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 16477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 16487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 16495778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStart: 16505778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 16513f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 16525778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 16535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16540e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (mState == FLUSHED) { 1655d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang setState(STARTED); 16563d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang if (mHavePendingInputBuffers) { 16573d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang onInputBufferAvailable(); 16583d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang mHavePendingInputBuffers = false; 16593d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang } 16600e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mCodec->signalResume(); 16610e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar PostReplyWithError(replyID, OK); 1662d9e0603a1be07dbb347c55050c7d4629ea7492e8Chong Zhang break; 16630e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar } else if (mState != CONFIGURED) { 1664c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 16655778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16665778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16685778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 16695778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(STARTING); 16705778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16715778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->initiateStart(); 16725778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 16735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 16745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 16755778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatStop: 1676c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber case kWhatRelease: 1677c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber { 1678aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber State targetState = 1679aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (msg->what() == kWhatStop) ? INITIALIZED : UNINITIALIZED; 1680aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 16813f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 1682c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 1683c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 168433223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung if (!((mFlags & kFlagIsComponentAllocated) && targetState == UNINITIALIZED) // See 1 168533223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung && mState != INITIALIZED 16860e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar && mState != CONFIGURED && !isExecuting()) { 168733223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 1) Permit release to shut down the component if allocated. 168833223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 168933223c4f97abb78fa8c92e1b8c817546f15d97e1Andy Hung // 2) We may be in "UNINITIALIZED" state already and 169052dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan // also shutdown the encoder/decoder without the 169103ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // client being aware of this if media server died while 169203ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // we were being stopped. The client would assume that 169303ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // after stop() returned, it would be safe to call release() 169403ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // and it should be in this case, no harm to allow a release() 169503ddaec84b65157af1dbf022a72de778dc59a63eAndreas Huber // if we're already uninitialized. 1696c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber sp<AMessage> response = new AMessage; 16976e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar status_t err = mState == targetState ? OK : INVALID_OPERATION; 16986e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar response->setInt32("err", err); 16996e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (err == OK && targetState == UNINITIALIZED) { 17006e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 17016e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1702c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber response->postReply(replyID); 1703c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber break; 1704c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber } 1705c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 1706aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber if (mFlags & kFlagSawMediaServerDie) { 1707aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // It's dead, Jim. Don't expect initiateShutdown to yield 1708aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // any useful results now... 1709aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(UNINITIALIZED); 17106e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar if (targetState == UNINITIALIZED) { 17116e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar mComponentName.clear(); 17126e029f0ba9a3b421eb7273a095305f7998e9aa5aLajos Molnar } 1713aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber (new AMessage)->postReply(replyID); 1714aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber break; 1715aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber } 1716aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1717c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber mReplyID = replyID; 1718aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber setState(msg->what() == kWhatStop ? STOPPING : RELEASING); 1719aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber 1720aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mCodec->initiateShutdown( 1721aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber msg->what() == kWhatStop /* keepComponentAllocated */); 1722c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber 17235778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 17245778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17255778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17275778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputBuffer: 17285778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 17293f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 17305778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 17315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1732c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1733c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1734c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1735c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1736c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1737c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 17386507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden if (mHaveInputSurface) { 17396507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden ALOGE("dequeueInputBuffer can't be used with input surface"); 1740c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 17416507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden break; 17426507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden } 17436507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden 17445778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueInputBuffer(replyID, true /* new request */)) { 17455778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17485778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 17495778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 17505778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17515778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1752c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 17535778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17565778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueInputPending; 17575778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = replyID; 17585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17595778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 17605778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 17611d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueInputTimedOut, this); 17625778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 17635778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueInputTimeoutGeneration); 17645778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 17655778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17665778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17675778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17685778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17695778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueInputTimedOut: 17705778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 17715778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 17725778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 17735778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17745778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueInputTimeoutGeneration) { 17755778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 17765778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17795778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueInputPending); 17805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1781c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueInputReplyID, -EAGAIN); 17825778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17835778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueInputPending; 17845778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueInputReplyID = 0; 17855778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 17865778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 17875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 17885778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatQueueInputBuffer: 17895778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 17903f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 17915778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 17925778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1793251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1794c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 17955778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1796251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1797251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1798251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 17995778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18005778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18015778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onQueueInputBuffer(msg); 18025778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1803c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 18045778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18055778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18065778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18075778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputBuffer: 18085778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18093f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18105778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18115778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1812c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mFlags & kFlagIsAsync) { 1813c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang ALOGE("dequeueOutputBuffer can't be used in async mode"); 1814c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 1815c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang break; 1816c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 1817c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 18185778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (handleDequeueOutputBuffer(replyID, true /* new request */)) { 18195778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18205778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18225778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeoutUs; 18235778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeoutUs", &timeoutUs)); 18245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18255778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs == 0ll) { 1826c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, -EAGAIN); 18275778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18285778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18295778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18305778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags |= kFlagDequeueOutputPending; 18315778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = replyID; 18325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18335778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (timeoutUs > 0ll) { 18345778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> timeoutMsg = 18351d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar new AMessage(kWhatDequeueOutputTimedOut, this); 18365778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->setInt32( 18375778822d86b0337407514b9372562b86edfa91cdAndreas Huber "generation", ++mDequeueOutputTimeoutGeneration); 18385778822d86b0337407514b9372562b86edfa91cdAndreas Huber timeoutMsg->post(timeoutUs); 18395778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18405778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18415778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18425778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18435778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatDequeueOutputTimedOut: 18445778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18455778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t generation; 18465778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("generation", &generation)); 18475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18485778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (generation != mDequeueOutputTimeoutGeneration) { 18495778822d86b0337407514b9372562b86edfa91cdAndreas Huber // Obsolete 18505778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18515778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18525778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18535778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(mFlags & kFlagDequeueOutputPending); 18545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1855c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(mDequeueOutputReplyID, -EAGAIN); 18565778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18575778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagDequeueOutputPending; 18585778822d86b0337407514b9372562b86edfa91cdAndreas Huber mDequeueOutputReplyID = 0; 18595778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18605778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18615778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18625778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatReleaseOutputBuffer: 18635778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 18643f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18655778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 18665778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1867251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1868c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18695778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1870251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1871251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1872251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 18735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18745778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18755778822d86b0337407514b9372562b86edfa91cdAndreas Huber status_t err = onReleaseOutputBuffer(msg); 18765778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1877c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 18785778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 18795778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 18805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 18817cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden case kWhatSignalEndOfInputStream: 18827cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden { 18833f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 18847cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden CHECK(msg->senderAwaitsResponse(&replyID)); 18857cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 1886251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1887c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 18887cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 1889251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1890251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1891251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 18927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 18937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 18947cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mReplyID = replyID; 18957cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden mCodec->signalEndOfInputStream(); 18967cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden break; 18977cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden } 18987cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden 18995778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetBuffers: 19005778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19013f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19025778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 1903e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // Unfortunately widevine legacy source requires knowing all of the 1904e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar // codec input buffers, so we have to provide them even in async mode. 1905e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar int32_t widevine = 0; 1906e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar msg->findInt32("widevine", &widevine); 19075778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1908e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar if (!isExecuting() || ((mFlags & kFlagIsAsync) && !widevine)) { 1909c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19105778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1911251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1912251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1913251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19145778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19155778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19165778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex; 19175778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("portIndex", &portIndex)); 19185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19195778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<sp<ABuffer> > *dstBuffers; 19205778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findPointer("buffers", (void **)&dstBuffers)); 19215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19225778822d86b0337407514b9372562b86edfa91cdAndreas Huber dstBuffers->clear(); 19235778822d86b0337407514b9372562b86edfa91cdAndreas Huber const Vector<BufferInfo> &srcBuffers = mPortBuffers[portIndex]; 19245778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19255778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < srcBuffers.size(); ++i) { 19265778822d86b0337407514b9372562b86edfa91cdAndreas Huber const BufferInfo &info = srcBuffers.itemAt(i); 19275778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1928ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber dstBuffers->push_back( 19291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (portIndex == kPortIndexInput && mCrypto != NULL) 1930ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber ? info.mEncryptedData : info.mData); 19315778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19335778822d86b0337407514b9372562b86edfa91cdAndreas Huber (new AMessage)->postReply(replyID); 19345778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19355778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19365778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19375778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatFlush: 19385778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 19393f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19405778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19415778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1942251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung if (!isExecuting()) { 1943c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19445778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1945251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1946251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1947251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19485778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19495778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19505778822d86b0337407514b9372562b86edfa91cdAndreas Huber mReplyID = replyID; 19510e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar // TODO: skip flushing if already FLUSHED 19525778822d86b0337407514b9372562b86edfa91cdAndreas Huber setState(FLUSHING); 19535778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19545778822d86b0337407514b9372562b86edfa91cdAndreas Huber mCodec->signalFlush(); 19555778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodec(); 19565778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19575778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1959e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar case kWhatGetInputFormat: 19605778822d86b0337407514b9372562b86edfa91cdAndreas Huber case kWhatGetOutputFormat: 19615778822d86b0337407514b9372562b86edfa91cdAndreas Huber { 1962e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar sp<AMessage> format = 1963e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar (msg->what() == kWhatGetOutputFormat ? mOutputFormat : mInputFormat); 1964e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar 19653f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 19665778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 19675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1968e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar if ((mState != CONFIGURED && mState != STARTING && 19690e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != STARTED && mState != FLUSHING && 19700e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar mState != FLUSHED) 1971e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar || format == NULL) { 1972c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 19735778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 1974251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung } else if (mFlags & kFlagStickyError) { 1975251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung PostReplyWithError(replyID, getStickyError()); 1976251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung break; 19775778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19785778822d86b0337407514b9372562b86edfa91cdAndreas Huber 19795778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> response = new AMessage; 1980e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar response->setMessage("format", format); 19815778822d86b0337407514b9372562b86edfa91cdAndreas Huber response->postReply(replyID); 19825778822d86b0337407514b9372562b86edfa91cdAndreas Huber break; 19835778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 19845778822d86b0337407514b9372562b86edfa91cdAndreas Huber 1985496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber case kWhatRequestIDRFrame: 1986496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber { 1987496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber mCodec->signalRequestIDRFrame(); 1988496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber break; 1989496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber } 1990496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber 1991575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber case kWhatRequestActivityNotification: 1992575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber { 1993575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(mActivityNotify == NULL); 1994575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber CHECK(msg->findMessage("notify", &mActivityNotify)); 1995575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 1996575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber postActivityNotificationIfPossible(); 1997575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber break; 1998575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 1999575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2000717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo case kWhatGetName: 2001717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo { 20023f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2003717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo CHECK(msg->senderAwaitsResponse(&replyID)); 2004717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2005717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (mComponentName.empty()) { 2006c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, INVALID_OPERATION); 2007717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2008717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2009717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2010717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo sp<AMessage> response = new AMessage; 2011717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->setString("name", mComponentName.c_str()); 2012717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo response->postReply(replyID); 2013717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo break; 2014717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2015717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 2016a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber case kWhatSetParameters: 2017a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber { 20183f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar sp<AReplyToken> replyID; 2019a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->senderAwaitsResponse(&replyID)); 2020a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2021a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> params; 2022a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber CHECK(msg->findMessage("params", ¶ms)); 2023a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2024a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber status_t err = onSetParameters(params); 2025a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2026c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang PostReplyWithError(replyID, err); 2027a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber break; 2028a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber } 2029a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 20305778822d86b0337407514b9372562b86edfa91cdAndreas Huber default: 20315778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 20325778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 20335778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 20345778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20358ee516a515c70a492c395b67ce12e19e7d159804Andreas Hubervoid MediaCodec::extractCSD(const sp<AMessage> &format) { 20368ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.clear(); 20378ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20388ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber size_t i = 0; 20398ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber for (;;) { 20408ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd; 2041a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) { 20428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber break; 20438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20448ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20458ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.push_back(csd); 20468ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber ++i; 20478ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20488ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 2049a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGV("Found %zu pieces of codec specific data.", mCSD.size()); 20508ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 20518ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20528ee516a515c70a492c395b67ce12e19e7d159804Andreas Huberstatus_t MediaCodec::queueCSDInputBuffer(size_t bufferIndex) { 20538ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber CHECK(!mCSD.empty()); 20548ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20557bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar const BufferInfo *info = 20567bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar &mPortBuffers[kPortIndexInput].itemAt(bufferIndex); 20578ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20588ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber sp<ABuffer> csd = *mCSD.begin(); 20598ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber mCSD.erase(mCSD.begin()); 20608ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20618ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber const sp<ABuffer> &codecInputData = 20628ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber (mCrypto != NULL) ? info->mEncryptedData : info->mData; 20638ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20648ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber if (csd->size() > codecInputData->capacity()) { 20658ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return -EINVAL; 20668ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber } 20678ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20688ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber memcpy(codecInputData->data(), csd->data(), csd->size()); 20698ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20708ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber AString errorDetailMsg; 20718ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20721d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatQueueInputBuffer, this); 20738ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("index", bufferIndex); 20748ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("offset", 0); 20758ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setSize("size", csd->size()); 20768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt64("timeUs", 0ll); 20778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setInt32("flags", BUFFER_FLAG_CODECCONFIG); 20788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber msg->setPointer("errorDetailMsg", &errorDetailMsg); 20798ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20808ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber return onQueueInputBuffer(msg); 20818ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber} 20828ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber 20835778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::setState(State newState) { 20847541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (newState == INITIALIZED || newState == UNINITIALIZED) { 20855778822d86b0337407514b9372562b86edfa91cdAndreas Huber delete mSoftRenderer; 20865778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer = NULL; 20875778822d86b0337407514b9372562b86edfa91cdAndreas Huber 20881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mCrypto.clear(); 20897541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber setNativeWindow(NULL); 20905778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2091671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar mInputFormat.clear(); 20925778822d86b0337407514b9372562b86edfa91cdAndreas Huber mOutputFormat.clear(); 20935778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputFormatChanged; 20945778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagOutputBuffersChanged; 20955778822d86b0337407514b9372562b86edfa91cdAndreas Huber mFlags &= ~kFlagStickyError; 2096e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagIsEncoder; 2097e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mFlags &= ~kFlagGatherCodecSpecificData; 2098c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mFlags &= ~kFlagIsAsync; 2099251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung mStickyError = OK; 2100575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2101575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2102c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mCallback.clear(); 21035778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21045778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2105717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo if (newState == UNINITIALIZED) { 2106671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar // return any straggling buffers, e.g. if we got here on an error 2107671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar returnBuffersToCodec(); 2108671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar 2109aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // The component is gone, mediaserver's probably back up already 2110aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // but should definitely be back up should we try to instantiate 2111aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber // another component.. and the cycle continues. 2112aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber mFlags &= ~kFlagSawMediaServerDie; 2113717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo } 2114717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo 21155778822d86b0337407514b9372562b86edfa91cdAndreas Huber mState = newState; 21165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21175778822d86b0337407514b9372562b86edfa91cdAndreas Huber cancelPendingDequeueOperations(); 21182606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 21192606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang updateBatteryStat(); 21205778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21215778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21225778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodec() { 21235778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexInput); 21245778822d86b0337407514b9372562b86edfa91cdAndreas Huber returnBuffersToCodecOnPort(kPortIndexOutput); 21255778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21265778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21275778822d86b0337407514b9372562b86edfa91cdAndreas Hubervoid MediaCodec::returnBuffersToCodecOnPort(int32_t portIndex) { 21285778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 21297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 21305778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21315778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 21325778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21335778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 21345778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 21355778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21365778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify != NULL) { 21375778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> msg = info->mNotify; 21385778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 21395778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mOwnedByClient = false; 21405778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21415778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (portIndex == kPortIndexInput) { 21427fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar /* no error, just returning buffers */ 21437fa015217e618265ff5a844cf6961ecc316c81a4Lajos Molnar msg->setInt32("err", OK); 21445778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21455778822d86b0337407514b9372562b86edfa91cdAndreas Huber msg->post(); 21465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21475778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21485778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21495778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].clear(); 21505778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21525778822d86b0337407514b9372562b86edfa91cdAndreas Hubersize_t MediaCodec::updateBuffers( 21535778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t portIndex, const sp<AMessage> &msg) { 21545778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 21555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2156609b815a3131d22da38b2f452faa9f89daad4039Andy Hung uint32_t bufferID; 2157609b815a3131d22da38b2f452faa9f89daad4039Andy Hung CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID)); 21585778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21595778822d86b0337407514b9372562b86edfa91cdAndreas Huber Vector<BufferInfo> *buffers = &mPortBuffers[portIndex]; 21605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21615778822d86b0337407514b9372562b86edfa91cdAndreas Huber for (size_t i = 0; i < buffers->size(); ++i) { 21625778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &buffers->editItemAt(i); 21635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21645778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mBufferID == bufferID) { 21655778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(info->mNotify == NULL); 21665778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findMessage("reply", &info->mNotify)); 21675778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2168475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mFormat = 2169475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu (portIndex == kPortIndexInput) ? mInputFormat : mOutputFormat; 21705778822d86b0337407514b9372562b86edfa91cdAndreas Huber mAvailPortBuffers[portIndex].push_back(i); 21715778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21725778822d86b0337407514b9372562b86edfa91cdAndreas Huber return i; 21735778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21745778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 21755778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21765778822d86b0337407514b9372562b86edfa91cdAndreas Huber TRESPASS(); 21775778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21785778822d86b0337407514b9372562b86edfa91cdAndreas Huber return 0; 21795778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 21805778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21815778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) { 21825778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 21835778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t offset; 21845778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t size; 21855778822d86b0337407514b9372562b86edfa91cdAndreas Huber int64_t timeUs; 21865778822d86b0337407514b9372562b86edfa91cdAndreas Huber uint32_t flags; 21875778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 21885778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("offset", &offset)); 21895778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt64("timeUs", &timeUs)); 21905778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findInt32("flags", (int32_t *)&flags)); 21915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 21924b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const CryptoPlugin::SubSample *subSamples; 21934b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size_t numSubSamples; 21944b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *key; 21954b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber const uint8_t *iv; 21964b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::Mode mode = CryptoPlugin::kMode_Unencrypted; 21974b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 21984b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // We allow the simpler queueInputBuffer API to be used even in 21994b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber // secure mode, by fabricating a single unencrypted subSample. 22004b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CryptoPlugin::SubSample ss; 22014b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22024b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (msg->findSize("size", &size)) { 22034b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto != NULL) { 22044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfClearData = size; 22054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber ss.mNumBytesOfEncryptedData = 0; 22064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples = &ss; 22084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples = 1; 22094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber key = NULL; 22104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber iv = NULL; 22114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } else { 22134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (mCrypto == NULL) { 22144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber return -EINVAL; 22154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("subSamples", (void **)&subSamples)); 22184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findSize("numSubSamples", &numSubSamples)); 22194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("key", (void **)&key)); 22204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findPointer("iv", (void **)&iv)); 22214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber int32_t tmp; 22234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber CHECK(msg->findInt32("mode", &tmp)); 22244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber mode = (CryptoPlugin::Mode)tmp; 22264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size = 0; 22284b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber for (size_t i = 0; i < numSubSamples; ++i) { 22294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfClearData; 22304b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber size += subSamples[i].mNumBytesOfEncryptedData; 22314b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 22334b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 22345778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexInput].size()) { 22355778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 22365778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22375778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22385778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexInput].editItemAt(index); 22395778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22405778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 22415778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 22425778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22435778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22445778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (offset + size > info->mData->capacity()) { 22455778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 22465778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22475778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22485778822d86b0337407514b9372562b86edfa91cdAndreas Huber sp<AMessage> reply = info->mNotify; 22495778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->setRange(offset, size); 22505778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt64("timeUs", timeUs); 22515778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22525778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_EOS) { 22535778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("eos", true); 22545778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22555778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22565778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (flags & BUFFER_FLAG_CODECCONFIG) { 22575778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mData->meta()->setInt32("csd", true); 22585778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 22595778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mCrypto != NULL) { 22611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (size > info->mEncryptedData->capacity()) { 22621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -ERANGE; 2263ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2264ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 22655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg; 22665b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg)); 22675b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 2268fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong ssize_t result = mCrypto->decrypt( 22691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (mFlags & kFlagIsSecure) != 0, 22701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber key, 22711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber iv, 22721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mode, 2273c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker info->mSharedEncryptedBuffer, 2274c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker offset, 22754b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber subSamples, 22764b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber numSubSamples, 22775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mData->base(), 22785b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg); 22791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 2280fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong if (result < 0) { 2281fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong return result; 2282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2283ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2284fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong info->mData->setRange(0, result); 2285ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 2286ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 22877bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 22887bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 22897bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 22907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 22917bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 22922d8bedd05437b6fccdbc6bf70f673ffd86744d59Andreas Huber reply->setBuffer("buffer", info->mData); 22935778822d86b0337407514b9372562b86edfa91cdAndreas Huber reply->post(); 22945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 22955b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber info->mNotify = NULL; 22965b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 22975778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 22985778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 22995778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23005778822d86b0337407514b9372562b86edfa91cdAndreas Huberstatus_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) { 23015778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index; 23025778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(msg->findSize("index", &index)); 23035778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23045778822d86b0337407514b9372562b86edfa91cdAndreas Huber int32_t render; 23055778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (!msg->findInt32("render", &render)) { 23065778822d86b0337407514b9372562b86edfa91cdAndreas Huber render = 0; 23075778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23085778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23090e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar if (!isExecuting()) { 23105778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EINVAL; 23115778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23125778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23135778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (index >= mPortBuffers[kPortIndexOutput].size()) { 23145778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -ERANGE; 23155778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23165778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23175778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[kPortIndexOutput].editItemAt(index); 23185778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23195778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (info->mNotify == NULL || !info->mOwnedByClient) { 23205778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EACCES; 23215778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23225778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23237bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar // synchronization boundary for getBufferAndFormat 23247bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 23257bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23267bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = false; 23277bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 23287bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar 232979ee2399b67c7a11042c5904dc1309712a76f8cbJianzheng Zhou if (render && info->mData != NULL && info->mData->size() != 0) { 23305778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->setInt32("render", true); 23315778822d86b0337407514b9372562b86edfa91cdAndreas Huber 2332fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar int64_t timestampNs = 0; 2333fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (msg->findInt64("timestampNs", ×tampNs)) { 2334fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar info->mNotify->setInt64("timestampNs", timestampNs); 2335fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } else { 2336fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // TODO: it seems like we should use the timestamp 2337fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // in the (media)buffer as it potentially came from 2338fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // an input surface, but we did not propagate it prior to 2339fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar // API 20. Perhaps check for target SDK version. 2340fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#if 0 2341fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar if (info->mData->meta()->findInt64("timeUs", ×tampNs)) { 234247aea1f7c58f5302b16822f9e7e1763f2af04ef5Lajos Molnar ALOGV("using buffer PTS of %" PRId64, timestampNs); 2343fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar timestampNs *= 1000; 2344fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2345fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar#endif 2346fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar } 2347fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar 23485778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (mSoftRenderer != NULL) { 23495778822d86b0337407514b9372562b86edfa91cdAndreas Huber mSoftRenderer->render( 2350475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu info->mData->data(), info->mData->size(), 2351475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu timestampNs, NULL, info->mFormat); 23525778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23535778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23545778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23555778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify->post(); 23565778822d86b0337407514b9372562b86edfa91cdAndreas Huber info->mNotify = NULL; 23575778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23585778822d86b0337407514b9372562b86edfa91cdAndreas Huber return OK; 23595778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23605778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23615778822d86b0337407514b9372562b86edfa91cdAndreas Huberssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { 23625778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput); 23635778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23645778822d86b0337407514b9372562b86edfa91cdAndreas Huber List<size_t> *availBuffers = &mAvailPortBuffers[portIndex]; 23655778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23665778822d86b0337407514b9372562b86edfa91cdAndreas Huber if (availBuffers->empty()) { 23675778822d86b0337407514b9372562b86edfa91cdAndreas Huber return -EAGAIN; 23685778822d86b0337407514b9372562b86edfa91cdAndreas Huber } 23695778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23705778822d86b0337407514b9372562b86edfa91cdAndreas Huber size_t index = *availBuffers->begin(); 23715778822d86b0337407514b9372562b86edfa91cdAndreas Huber availBuffers->erase(availBuffers->begin()); 23725778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23735778822d86b0337407514b9372562b86edfa91cdAndreas Huber BufferInfo *info = &mPortBuffers[portIndex].editItemAt(index); 23745778822d86b0337407514b9372562b86edfa91cdAndreas Huber CHECK(!info->mOwnedByClient); 23757bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar { 23767bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar Mutex::Autolock al(mBufferLock); 23777bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar info->mOwnedByClient = true; 237803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar 237903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar // set image-data 238003c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat != NULL) { 238103c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar sp<ABuffer> imageData; 238203c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findBuffer("image-data", &imageData)) { 238303c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setBuffer("image-data", imageData); 238403c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 238503c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar int32_t left, top, right, bottom; 238603c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) { 238703c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar info->mData->meta()->setRect("crop-rect", left, top, right, bottom); 238803c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 238903c556ae1eb409ad088c49037e185946c54e1d25Lajos Molnar } 23907bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar } 23915778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23925778822d86b0337407514b9372562b86edfa91cdAndreas Huber return index; 23935778822d86b0337407514b9372562b86edfa91cdAndreas Huber} 23945778822d86b0337407514b9372562b86edfa91cdAndreas Huber 23957541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huberstatus_t MediaCodec::setNativeWindow( 23961a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian const sp<Surface> &surfaceTextureClient) { 23977541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber status_t err; 23987541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 23997541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (mNativeWindow != NULL) { 24007541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber err = native_window_api_disconnect( 24017541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA); 24027541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24037541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 24047541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ALOGW("native_window_api_disconnect returned an error: %s (%d)", 24057541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber strerror(-err), err); 24067541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24077541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24087541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow.clear(); 24097541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24107541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24117541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (surfaceTextureClient != NULL) { 24127541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber err = native_window_api_connect( 24137541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber surfaceTextureClient.get(), NATIVE_WINDOW_API_MEDIA); 24147541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24157541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber if (err != OK) { 24167541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber ALOGE("native_window_api_connect returned an error: %s (%d)", 24177541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber strerror(-err), err); 24187541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24197541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber return err; 24207541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24217541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24227541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber mNativeWindow = surfaceTextureClient; 24237541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber } 24247541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 24257541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber return OK; 24267541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber} 24277541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber 2428c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onInputBufferAvailable() { 2429c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2430c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexInput)) >= 0) { 2431c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2432c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_INPUT_AVAILABLE); 2433c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2434c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2435c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2436c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2437c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2438c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputBufferAvailable() { 2439c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t index; 2440c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang while ((index = dequeuePortBuffer(kPortIndexOutput)) >= 0) { 2441c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang const sp<ABuffer> &buffer = 2442c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang mPortBuffers[kPortIndexOutput].itemAt(index).mData; 2443c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2444c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_AVAILABLE); 2445c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("index", index); 2446c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("offset", buffer->offset()); 2447c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setSize("size", buffer->size()); 2448c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2449c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int64_t timeUs; 2450c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt64("timeUs", &timeUs)); 2451c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2452c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt64("timeUs", timeUs); 2453c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2454c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang int32_t omxFlags; 2455c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang CHECK(buffer->meta()->findInt32("omxFlags", &omxFlags)); 2456c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2457c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang uint32_t flags = 0; 2458c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 2459c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_SYNCFRAME; 2460c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2461c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 2462c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_CODECCONFIG; 2463c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2464c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (omxFlags & OMX_BUFFERFLAG_EOS) { 2465c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang flags |= BUFFER_FLAG_EOS; 2466c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2467c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2468c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("flags", flags); 2469c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2470c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2471c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2472c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2473c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2474749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhangvoid MediaCodec::onError(status_t err, int32_t actionCode, const char *detail) { 2475c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2476c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2477c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_ERROR); 2478c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("err", err); 2479749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setInt32("actionCode", actionCode); 2480749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang 2481749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang if (detail != NULL) { 2482749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang msg->setString("detail", detail); 2483749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang } 2484c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2485c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2486c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2487c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2488c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2489c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhangvoid MediaCodec::onOutputFormatChanged() { 2490c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang if (mCallback != NULL) { 2491c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang sp<AMessage> msg = mCallback->dup(); 2492c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setInt32("callbackID", CB_OUTPUT_FORMAT_CHANGED); 2493c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->setMessage("format", mOutputFormat); 2494c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang msg->post(); 2495c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang } 2496c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang} 2497c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2498c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang 2499575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Hubervoid MediaCodec::postActivityNotificationIfPossible() { 2500575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber if (mActivityNotify == NULL) { 2501575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber return; 2502575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2503575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2504e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang bool isErrorOrOutputChanged = 2505e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang (mFlags & (kFlagStickyError 2506575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber | kFlagOutputBuffersChanged 2507e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang | kFlagOutputFormatChanged)); 2508e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2509e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged 2510575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexInput].empty() 2511575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber || !mAvailPortBuffers[kPortIndexOutput].empty()) { 2512e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("input-buffers", 2513e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexInput].size()); 2514e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang 2515e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang if (isErrorOrOutputChanged) { 2516e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang // we want consumer to dequeue as many times as it can 2517e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", INT32_MAX); 2518e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } else { 2519e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mActivityNotify->setInt32("output-buffers", 2520e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang mAvailPortBuffers[kPortIndexOutput].size()); 2521e47d44486f0a9f9b828b01d0fbaf84f5573f0aa2Chong Zhang } 2522575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify->post(); 2523575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber mActivityNotify.clear(); 2524575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber } 2525575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber} 2526575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber 2527a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::setParameters(const sp<AMessage> ¶ms) { 25281d15ab58bf8239069ef343de6cb21aabf3ef7d78Lajos Molnar sp<AMessage> msg = new AMessage(kWhatSetParameters, this); 2529a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber msg->setMessage("params", params); 2530a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2531a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber sp<AMessage> response; 2532a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return PostAndAwaitResponse(msg, &response); 2533a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2534a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2535a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huberstatus_t MediaCodec::onSetParameters(const sp<AMessage> ¶ms) { 2536a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber mCodec->signalSetParameters(params); 2537a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2538a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber return OK; 2539a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber} 2540a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber 2541e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huberstatus_t MediaCodec::amendOutputFormatWithCodecSpecificData( 2542e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const sp<ABuffer> &buffer) { 2543e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber AString mime; 2544e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber CHECK(mOutputFormat->findString("mime", &mime)); 2545e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2546e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) { 2547e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // Codec specific data should be SPS and PPS in a single buffer, 2548e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // each prefixed by a startcode (0x00 0x00 0x00 0x01). 2549e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // We separate the two and put them into the output format 2550e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // under the keys "csd-0" and "csd-1". 2551e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2552e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber unsigned csdIndex = 0; 2553e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2554e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *data = buffer->data(); 2555e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t size = buffer->size(); 2556e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2557e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber const uint8_t *nalStart; 2558e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber size_t nalSize; 2559e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) { 2560e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber sp<ABuffer> csd = new ABuffer(nalSize + 4); 2561e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data(), "\x00\x00\x00\x01", 4); 2562e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber memcpy(csd->data() + 4, nalStart, nalSize); 2563e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2564e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer( 2565a1e8944a21e5833b7aadc451776f11797f5f9273Elliott Hughes AStringPrintf("csd-%u", csdIndex).c_str(), csd); 2566e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2567e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber ++csdIndex; 2568e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2569e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2570e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber if (csdIndex != 2) { 2571e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return ERROR_MALFORMED; 2572e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2573e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } else { 2574e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // For everything else we just stash the codec specific data into 2575e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber // the output format as a single piece of csd under "csd-0". 2576e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber mOutputFormat->setBuffer("csd-0", buffer); 2577e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber } 2578e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 2579e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber return OK; 2580e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber} 2581e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber 25822606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhangvoid MediaCodec::updateBatteryStat() { 25832606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mState == CONFIGURED && !mBatteryStatNotified) { 25842606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier& notifier(BatteryNotifier::getInstance()); 25852606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 25862606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mIsVideo) { 25872606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStartVideo(); 25882606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else { 25892606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStartAudio(); 25902606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 25912606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 25922606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = true; 25932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else if (mState == UNINITIALIZED && mBatteryStatNotified) { 25942606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang BatteryNotifier& notifier(BatteryNotifier::getInstance()); 25952606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 25962606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang if (mIsVideo) { 25972606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStopVideo(); 25982606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } else { 25992606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang notifier.noteStopAudio(); 26002606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 26012606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26022606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang mBatteryStatNotified = false; 26032606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang } 26042606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang} 26052606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang 26065778822d86b0337407514b9372562b86edfa91cdAndreas Huber} // namespace android 2607