diff -r 000000000000 -r 6474c204b198 content/media/omx/mediaresourcemanager/MediaResourceManagerService.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/media/omx/mediaresourcemanager/MediaResourceManagerService.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "MediaResourceManagerService" + +#include +#include +#include + +#include "MediaResourceManagerClient.h" +#include "MediaResourceManagerService.h" + +namespace android { + +/* static */ +void MediaResourceManagerService::instantiate() { + defaultServiceManager()->addService( + String16("media.resource_manager"), new MediaResourceManagerService()); +} + +MediaResourceManagerService::MediaResourceManagerService() + : mVideoDecoderCount(VIDEO_DECODER_COUNT) +{ + mLooper = new ALooper; + mLooper->setName("MediaResourceManagerService"); + + mReflector = new AHandlerReflector(this); + // Register AMessage handler to ALooper. + mLooper->registerHandler(mReflector); + // Start ALooper thread. + mLooper->start(); +} + +MediaResourceManagerService::~MediaResourceManagerService() +{ + // Unregister AMessage handler from ALooper. + mLooper->unregisterHandler(mReflector->id()); + // Stop ALooper thread. + mLooper->stop(); +} + +void MediaResourceManagerService::binderDied(const wp& who) +{ + if (who != NULL) { + Mutex::Autolock autoLock(mLock); + sp binder = who.promote(); + if (binder != NULL) { + cancelClientLocked(binder); + } + } +} + +void MediaResourceManagerService::requestMediaResource(const sp& client, int resourceType) +{ + if (resourceType != MediaResourceManagerClient::HW_VIDEO_DECODER) { + // Support only HW_VIDEO_DECODER + return; + } + + { + Mutex::Autolock autoLock(mLock); + sp binder = client->asBinder(); + mVideoCodecRequestQueue.push_back(binder); + binder->linkToDeath(this); + } + + sp notify = + new AMessage(kNotifyRequest, mReflector->id()); + // Post AMessage to MediaResourceManagerService via ALooper. + notify->post(); +} + +status_t MediaResourceManagerService::cancelClient(const sp& client) +{ + { + Mutex::Autolock autoLock(mLock); + sp binder = client->asBinder(); + cancelClientLocked(binder); + } + + sp notify = + new AMessage(kNotifyRequest, mReflector->id()); + // Post AMessage to MediaResourceManagerService via ALooper. + notify->post(); + + return NO_ERROR; +} + +// Called on ALooper thread. +void MediaResourceManagerService::onMessageReceived(const sp &msg) +{ + Mutex::Autolock autoLock(mLock); + + // Exit if no request. + if (mVideoCodecRequestQueue.empty()) { + return; + } + + // Check if resource is available + int found = -1; + for (int i=0 ; i client = interface_cast(mVideoDecoderSlots[found].mClient); + client->statusChanged(MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED); +} + +void MediaResourceManagerService::cancelClientLocked(const sp& binder) +{ + // Clear the request from request queue. + Fifo::iterator it(mVideoCodecRequestQueue.begin()); + while (it != mVideoCodecRequestQueue.end()) { + if ((*it).get() == binder.get()) { + mVideoCodecRequestQueue.erase(it); + break; + } + it++; + } + + // Clear the client from the resource + for (int i=0 ; iunlinkToDeath(this); +} + +}; // namespace android +