OMXClient.cpp revision 408b8e1073385d0d09bb96b9952f84731a0b4aeb
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "OMXClient" 19#include <utils/Log.h> 20 21#include <sys/socket.h> 22 23#undef NDEBUG 24#include <assert.h> 25 26#include <binder/IServiceManager.h> 27#include <media/IMediaPlayerService.h> 28#include <media/IOMX.h> 29#include <media/stagefright/OMXClient.h> 30 31namespace android { 32 33OMXClient::OMXClient() { 34} 35 36OMXClient::~OMXClient() { 37 disconnect(); 38} 39 40status_t OMXClient::connect() { 41 Mutex::Autolock autoLock(mLock); 42 43 sp<IServiceManager> sm = defaultServiceManager(); 44 sp<IBinder> binder = sm->getService(String16("media.player")); 45 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 46 47 assert(service.get() != NULL); 48 49 mOMX = service->createOMX(); 50 assert(mOMX.get() != NULL); 51 52 mReflector = new OMXClientReflector(this); 53 54 return OK; 55} 56 57void OMXClient::disconnect() { 58 Mutex::Autolock autoLock(mLock); 59 60 if (mReflector.get() != NULL) { 61 return; 62 } 63 64 assert(mObservers.isEmpty()); 65 66 mReflector->reset(); 67 mReflector.clear(); 68} 69 70status_t OMXClient::registerObserver( 71 IOMX::node_id node, OMXObserver *observer) { 72 Mutex::Autolock autoLock(&mLock); 73 74 ssize_t index = mObservers.indexOfKey(node); 75 if (index >= 0) { 76 return UNKNOWN_ERROR; 77 } 78 79 mObservers.add(node, observer); 80 observer->start(); 81 82 mOMX->observe_node(node, mReflector); 83 84 return OK; 85} 86 87void OMXClient::unregisterObserver(IOMX::node_id node) { 88 Mutex::Autolock autoLock(mLock); 89 90 ssize_t index = mObservers.indexOfKey(node); 91 assert(index >= 0); 92 93 if (index < 0) { 94 return; 95 } 96 97 OMXObserver *observer = mObservers.valueAt(index); 98 observer->stop(); 99 mObservers.removeItemsAt(index); 100} 101 102bool OMXClient::onOMXMessage(const omx_message &msg) { 103 bool done = false; 104 105 switch (msg.type) { 106 case omx_message::EVENT: 107 { 108 LOGV("OnEvent node:%p event:%d data1:%ld data2:%ld", 109 msg.u.event_data.node, 110 msg.u.event_data.event, 111 msg.u.event_data.data1, 112 msg.u.event_data.data2); 113 114 break; 115 } 116 117 case omx_message::FILL_BUFFER_DONE: 118 { 119 LOGV("FillBufferDone %p", msg.u.extended_buffer_data.buffer); 120 break; 121 } 122 123 case omx_message::EMPTY_BUFFER_DONE: 124 { 125 LOGV("EmptyBufferDone %p", msg.u.buffer_data.buffer); 126 break; 127 } 128 129 default: 130 LOGE("received unknown omx_message type %d", msg.type); 131 break; 132 } 133 134 Mutex::Autolock autoLock(mLock); 135 ssize_t index = mObservers.indexOfKey(msg.u.buffer_data.node); 136 137 if (index >= 0) { 138 mObservers.editValueAt(index)->postMessage(msg); 139 } 140 141 return done; 142} 143 144//////////////////////////////////////////////////////////////////////////////// 145 146OMXObserver::OMXObserver() { 147} 148 149OMXObserver::~OMXObserver() { 150} 151 152void OMXObserver::start() { 153 pthread_attr_t attr; 154 pthread_attr_init(&attr); 155 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 156 157 int err = pthread_create(&mThread, &attr, ThreadWrapper, this); 158 assert(err == 0); 159 160 pthread_attr_destroy(&attr); 161} 162 163void OMXObserver::stop() { 164 omx_message msg; 165 msg.type = omx_message::QUIT_OBSERVER; 166 postMessage(msg); 167 168 void *dummy; 169 pthread_join(mThread, &dummy); 170} 171 172void OMXObserver::postMessage(const omx_message &msg) { 173 Mutex::Autolock autoLock(mLock); 174 mQueue.push_back(msg); 175 mQueueNotEmpty.signal(); 176} 177 178// static 179void *OMXObserver::ThreadWrapper(void *me) { 180 static_cast<OMXObserver *>(me)->threadEntry(); 181 182 return NULL; 183} 184 185void OMXObserver::threadEntry() { 186 for (;;) { 187 omx_message msg; 188 189 { 190 Mutex::Autolock autoLock(mLock); 191 while (mQueue.empty()) { 192 mQueueNotEmpty.wait(mLock); 193 } 194 195 msg = *mQueue.begin(); 196 mQueue.erase(mQueue.begin()); 197 } 198 199 if (msg.type == omx_message::QUIT_OBSERVER) { 200 break; 201 } 202 203 onOMXMessage(msg); 204 } 205} 206 207//////////////////////////////////////////////////////////////////////////////// 208 209OMXClientReflector::OMXClientReflector(OMXClient *client) 210 : mClient(client) { 211} 212 213void OMXClientReflector::on_message(const omx_message &msg) { 214 if (mClient != NULL) { 215 mClient->onOMXMessage(msg); 216 } 217} 218 219void OMXClientReflector::reset() { 220 mClient = NULL; 221} 222 223} // namespace android 224