Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 //#define LOG_NDEBUG 0
8 #define LOG_TAG "MediaResourceManagerService"
10 #include <binder/IServiceManager.h>
11 #include <media/stagefright/foundation/AMessage.h>
12 #include <utils/Log.h>
14 #include "MediaResourceManagerClient.h"
15 #include "MediaResourceManagerService.h"
17 namespace android {
19 /* static */
20 void MediaResourceManagerService::instantiate() {
21 defaultServiceManager()->addService(
22 String16("media.resource_manager"), new MediaResourceManagerService());
23 }
25 MediaResourceManagerService::MediaResourceManagerService()
26 : mVideoDecoderCount(VIDEO_DECODER_COUNT)
27 {
28 mLooper = new ALooper;
29 mLooper->setName("MediaResourceManagerService");
31 mReflector = new AHandlerReflector<MediaResourceManagerService>(this);
32 // Register AMessage handler to ALooper.
33 mLooper->registerHandler(mReflector);
34 // Start ALooper thread.
35 mLooper->start();
36 }
38 MediaResourceManagerService::~MediaResourceManagerService()
39 {
40 // Unregister AMessage handler from ALooper.
41 mLooper->unregisterHandler(mReflector->id());
42 // Stop ALooper thread.
43 mLooper->stop();
44 }
46 void MediaResourceManagerService::binderDied(const wp<IBinder>& who)
47 {
48 if (who != NULL) {
49 Mutex::Autolock autoLock(mLock);
50 sp<IBinder> binder = who.promote();
51 if (binder != NULL) {
52 cancelClientLocked(binder);
53 }
54 }
55 }
57 void MediaResourceManagerService::requestMediaResource(const sp<IMediaResourceManagerClient>& client, int resourceType)
58 {
59 if (resourceType != MediaResourceManagerClient::HW_VIDEO_DECODER) {
60 // Support only HW_VIDEO_DECODER
61 return;
62 }
64 {
65 Mutex::Autolock autoLock(mLock);
66 sp<IBinder> binder = client->asBinder();
67 mVideoCodecRequestQueue.push_back(binder);
68 binder->linkToDeath(this);
69 }
71 sp<AMessage> notify =
72 new AMessage(kNotifyRequest, mReflector->id());
73 // Post AMessage to MediaResourceManagerService via ALooper.
74 notify->post();
75 }
77 status_t MediaResourceManagerService::cancelClient(const sp<IMediaResourceManagerClient>& client)
78 {
79 {
80 Mutex::Autolock autoLock(mLock);
81 sp<IBinder> binder = client->asBinder();
82 cancelClientLocked(binder);
83 }
85 sp<AMessage> notify =
86 new AMessage(kNotifyRequest, mReflector->id());
87 // Post AMessage to MediaResourceManagerService via ALooper.
88 notify->post();
90 return NO_ERROR;
91 }
93 // Called on ALooper thread.
94 void MediaResourceManagerService::onMessageReceived(const sp<AMessage> &msg)
95 {
96 Mutex::Autolock autoLock(mLock);
98 // Exit if no request.
99 if (mVideoCodecRequestQueue.empty()) {
100 return;
101 }
103 // Check if resource is available
104 int found = -1;
105 for (int i=0 ; i<mVideoDecoderCount ; i++) {
106 if (!mVideoDecoderSlots[i].mClient.get()) {
107 found = i;
108 }
109 }
111 // Exit if no resource is available.
112 if (found == -1) {
113 return;
114 }
116 // Assign resource to IMediaResourceManagerClient
117 Fifo::iterator front(mVideoCodecRequestQueue.begin());
118 mVideoDecoderSlots[found].mClient = *front;
119 mVideoCodecRequestQueue.erase(front);
120 // Notify resource assignment to the client.
121 sp<IMediaResourceManagerClient> client = interface_cast<IMediaResourceManagerClient>(mVideoDecoderSlots[found].mClient);
122 client->statusChanged(MediaResourceManagerClient::CLIENT_STATE_RESOURCE_ASSIGNED);
123 }
125 void MediaResourceManagerService::cancelClientLocked(const sp<IBinder>& binder)
126 {
127 // Clear the request from request queue.
128 Fifo::iterator it(mVideoCodecRequestQueue.begin());
129 while (it != mVideoCodecRequestQueue.end()) {
130 if ((*it).get() == binder.get()) {
131 mVideoCodecRequestQueue.erase(it);
132 break;
133 }
134 it++;
135 }
137 // Clear the client from the resource
138 for (int i=0 ; i<mVideoDecoderCount ; i++) {
139 if (mVideoDecoderSlots[i].mClient.get() == binder.get()) {
140 mVideoDecoderSlots[i].mClient = NULL;
141 }
142 }
143 binder->unlinkToDeath(this);
144 }
146 }; // namespace android