OMXClient.cpp revision 0c89199745bc1bf05b997fc7c342017807676b6f
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#include <binder/IServiceManager.h> 24#include <media/IMediaPlayerService.h> 25#include <media/IOMX.h> 26#include <media/stagefright/MediaDebug.h> 27#include <media/stagefright/OMXClient.h> 28 29namespace android { 30 31OMXClient::OMXClient() { 32} 33 34OMXClient::~OMXClient() { 35 disconnect(); 36} 37 38status_t OMXClient::connect() { 39 Mutex::Autolock autoLock(mLock); 40 41 sp<IServiceManager> sm = defaultServiceManager(); 42 sp<IBinder> binder = sm->getService(String16("media.player")); 43 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 44 45 CHECK(service.get() != NULL); 46 47 mOMX = service->createOMX(); 48 CHECK(mOMX.get() != NULL); 49 50 mReflector = new OMXClientReflector(this); 51 52 return OK; 53} 54 55void OMXClient::disconnect() { 56 Mutex::Autolock autoLock(mLock); 57 58 if (mReflector.get() != NULL) { 59 return; 60 } 61 62 CHECK(mObservers.isEmpty()); 63 64 mReflector->reset(); 65 mReflector.clear(); 66} 67 68status_t OMXClient::registerObserver( 69 IOMX::node_id node, OMXObserver *observer) { 70 Mutex::Autolock autoLock(&mLock); 71 72 ssize_t index = mObservers.indexOfKey(node); 73 if (index >= 0) { 74 return UNKNOWN_ERROR; 75 } 76 77 mObservers.add(node, observer); 78 observer->start(); 79 80 mOMX->observe_node(node, mReflector); 81 82 return OK; 83} 84 85void OMXClient::unregisterObserver(IOMX::node_id node) { 86 Mutex::Autolock autoLock(mLock); 87 88 ssize_t index = mObservers.indexOfKey(node); 89 CHECK(index >= 0); 90 91 if (index < 0) { 92 return; 93 } 94 95 OMXObserver *observer = mObservers.valueAt(index); 96 observer->stop(); 97 mObservers.removeItemsAt(index); 98} 99 100bool OMXClient::onOMXMessage(const omx_message &msg) { 101 bool done = false; 102 103 switch (msg.type) { 104 case omx_message::EVENT: 105 { 106 LOGV("OnEvent node:%p event:%d data1:%ld data2:%ld", 107 msg.u.event_data.node, 108 msg.u.event_data.event, 109 msg.u.event_data.data1, 110 msg.u.event_data.data2); 111 112 break; 113 } 114 115 case omx_message::FILL_BUFFER_DONE: 116 { 117 LOGV("FillBufferDone %p", msg.u.extended_buffer_data.buffer); 118 break; 119 } 120 121 case omx_message::EMPTY_BUFFER_DONE: 122 { 123 LOGV("EmptyBufferDone %p", msg.u.buffer_data.buffer); 124 break; 125 } 126 127 default: 128 LOGE("received unknown omx_message type %d", msg.type); 129 break; 130 } 131 132 Mutex::Autolock autoLock(mLock); 133 ssize_t index = mObservers.indexOfKey(msg.node); 134 135 if (index >= 0) { 136 mObservers.editValueAt(index)->postMessage(msg); 137 } 138 139 return done; 140} 141 142//////////////////////////////////////////////////////////////////////////////// 143 144OMXObserver::OMXObserver() { 145} 146 147OMXObserver::~OMXObserver() { 148} 149 150void OMXObserver::start() { 151 pthread_attr_t attr; 152 pthread_attr_init(&attr); 153 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 154 155 int err = pthread_create(&mThread, &attr, ThreadWrapper, this); 156 CHECK_EQ(err, 0); 157 158 pthread_attr_destroy(&attr); 159} 160 161void OMXObserver::stop() { 162 omx_message msg; 163 msg.type = omx_message::QUIT_OBSERVER; 164 postMessage(msg); 165 166 void *dummy; 167 pthread_join(mThread, &dummy); 168} 169 170void OMXObserver::postMessage(const omx_message &msg) { 171 Mutex::Autolock autoLock(mLock); 172 mQueue.push_back(msg); 173 mQueueNotEmpty.signal(); 174} 175 176// static 177void *OMXObserver::ThreadWrapper(void *me) { 178 static_cast<OMXObserver *>(me)->threadEntry(); 179 180 return NULL; 181} 182 183void OMXObserver::threadEntry() { 184 for (;;) { 185 omx_message msg; 186 187 { 188 Mutex::Autolock autoLock(mLock); 189 while (mQueue.empty()) { 190 mQueueNotEmpty.wait(mLock); 191 } 192 193 msg = *mQueue.begin(); 194 mQueue.erase(mQueue.begin()); 195 } 196 197 if (msg.type == omx_message::QUIT_OBSERVER) { 198 break; 199 } 200 201 onOMXMessage(msg); 202 } 203} 204 205//////////////////////////////////////////////////////////////////////////////// 206 207OMXClientReflector::OMXClientReflector(OMXClient *client) 208 : mClient(client) { 209} 210 211void OMXClientReflector::on_message(const omx_message &msg) { 212 if (mClient != NULL) { 213 mClient->onOMXMessage(msg); 214 } 215} 216 217void OMXClientReflector::reset() { 218 mClient = NULL; 219} 220 221} // namespace android 222