1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/omx/mediaresourcemanager/MediaResourceManagerService.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,147 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +//#define LOG_NDEBUG 0 1.11 +#define LOG_TAG "MediaResourceManagerService" 1.12 + 1.13 +#include <binder/IServiceManager.h> 1.14 +#include <media/stagefright/foundation/AMessage.h> 1.15 +#include <utils/Log.h> 1.16 + 1.17 +#include "MediaResourceManagerClient.h" 1.18 +#include "MediaResourceManagerService.h" 1.19 + 1.20 +namespace android { 1.21 + 1.22 +/* static */ 1.23 +void MediaResourceManagerService::instantiate() { 1.24 + defaultServiceManager()->addService( 1.25 + String16("media.resource_manager"), new MediaResourceManagerService()); 1.26 +} 1.27 + 1.28 +MediaResourceManagerService::MediaResourceManagerService() 1.29 + : mVideoDecoderCount(VIDEO_DECODER_COUNT) 1.30 +{ 1.31 + mLooper = new ALooper; 1.32 + mLooper->setName("MediaResourceManagerService"); 1.33 + 1.34 + mReflector = new AHandlerReflector<MediaResourceManagerService>(this); 1.35 + // Register AMessage handler to ALooper. 1.36 + mLooper->registerHandler(mReflector); 1.37 + // Start ALooper thread. 1.38 + mLooper->start(); 1.39 +} 1.40 + 1.41 +MediaResourceManagerService::~MediaResourceManagerService() 1.42 +{ 1.43 + // Unregister AMessage handler from ALooper. 1.44 + mLooper->unregisterHandler(mReflector->id()); 1.45 + // Stop ALooper thread. 1.46 + mLooper->stop(); 1.47 +} 1.48 + 1.49 +void MediaResourceManagerService::binderDied(const wp<IBinder>& who) 1.50 +{ 1.51 + if (who != NULL) { 1.52 + Mutex::Autolock autoLock(mLock); 1.53 + sp<IBinder> binder = who.promote(); 1.54 + if (binder != NULL) { 1.55 + cancelClientLocked(binder); 1.56 + } 1.57 + } 1.58 +} 1.59 + 1.60 +void MediaResourceManagerService::requestMediaResource(const sp<IMediaResourceManagerClient>& client, int resourceType) 1.61 +{ 1.62 + if (resourceType != MediaResourceManagerClient::HW_VIDEO_DECODER) { 1.63 + // Support only HW_VIDEO_DECODER 1.64 + return; 1.65 + } 1.66 + 1.67 + { 1.68 + Mutex::Autolock autoLock(mLock); 1.69 + sp<IBinder> binder = client->asBinder(); 1.70 + mVideoCodecRequestQueue.push_back(binder); 1.71 + binder->linkToDeath(this); 1.72 + } 1.73 + 1.74 + sp<AMessage> notify = 1.75 + new AMessage(kNotifyRequest, mReflector->id()); 1.76 + // Post AMessage to MediaResourceManagerService via ALooper. 1.77 + notify->post(); 1.78 +} 1.79 + 1.80 +status_t MediaResourceManagerService::cancelClient(const sp<IMediaResourceManagerClient>& client) 1.81 +{ 1.82 + { 1.83 + Mutex::Autolock autoLock(mLock); 1.84 + sp<IBinder> binder = client->asBinder(); 1.85 + cancelClientLocked(binder); 1.86 + } 1.87 + 1.88 + sp<AMessage> notify = 1.89 + new AMessage(kNotifyRequest, mReflector->id()); 1.90 + // Post AMessage to MediaResourceManagerService via ALooper. 1.91 + notify->post(); 1.92 + 1.93 + return NO_ERROR; 1.94 +} 1.95 + 1.96 +// Called on ALooper thread. 1.97 +void MediaResourceManagerService::onMessageReceived(const sp<AMessage> &msg) 1.98 +{ 1.99 + Mutex::Autolock autoLock(mLock); 1.100 + 1.101 + // Exit if no request. 1.102 + if (mVideoCodecRequestQueue.empty()) { 1.103 + return; 1.104 + } 1.105 + 1.106 + // Check if resource is available 1.107 + int found = -1; 1.108 + for (int i=0 ; i<mVideoDecoderCount ; i++) { 1.109 + if (!mVideoDecoderSlots[i].mClient.get()) { 1.110 + found = i; 1.111 + } 1.112 + } 1.113 + 1.114 + // Exit if no resource is available. 1.115 + if (found == -1) { 1.116 + return; 1.117 + } 1.118 + 1.119 + // Assign resource to IMediaResourceManagerClient 1.120 + Fifo::iterator front(mVideoCodecRequestQueue.begin()); 1.121 + mVideoDecoderSlots[found].mClient = *front; 1.122 + mVideoCodecRequestQueue.erase(front); 1.123 + // Notify resource assignment to the client. 1.124 + sp<IMediaResourceManagerClient> client = interface_cast<IMediaResourceManagerClient>(mVideoDecoderSlots[found].mClient); 1.125 + client->statusChanged(MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED); 1.126 +} 1.127 + 1.128 +void MediaResourceManagerService::cancelClientLocked(const sp<IBinder>& binder) 1.129 +{ 1.130 + // Clear the request from request queue. 1.131 + Fifo::iterator it(mVideoCodecRequestQueue.begin()); 1.132 + while (it != mVideoCodecRequestQueue.end()) { 1.133 + if ((*it).get() == binder.get()) { 1.134 + mVideoCodecRequestQueue.erase(it); 1.135 + break; 1.136 + } 1.137 + it++; 1.138 + } 1.139 + 1.140 + // Clear the client from the resource 1.141 + for (int i=0 ; i<mVideoDecoderCount ; i++) { 1.142 + if (mVideoDecoderSlots[i].mClient.get() == binder.get()) { 1.143 + mVideoDecoderSlots[i].mClient = NULL; 1.144 + } 1.145 + } 1.146 + binder->unlinkToDeath(this); 1.147 +} 1.148 + 1.149 +}; // namespace android 1.150 +