OMXClient.cpp revision e9c52da6fdb755ed832325c2fe4fe5b3bc4c9eed
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 <binder/IServiceManager.h> 22#include <media/IMediaPlayerService.h> 23#include <media/stagefright/foundation/ADebug.h> 24#include <media/stagefright/OMXClient.h> 25#include <utils/KeyedVector.h> 26 27#include "include/OMX.h" 28 29namespace android { 30 31struct MuxOMX : public IOMX { 32 MuxOMX(const sp<IOMX> &remoteOMX); 33 virtual ~MuxOMX(); 34 35 virtual IBinder *onAsBinder() { return NULL; } 36 37 virtual bool livesLocally(pid_t pid); 38 39 virtual status_t listNodes(List<ComponentInfo> *list); 40 41 virtual status_t allocateNode( 42 const char *name, const sp<IOMXObserver> &observer, 43 node_id *node); 44 45 virtual status_t freeNode(node_id node); 46 47 virtual status_t sendCommand( 48 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param); 49 50 virtual status_t getParameter( 51 node_id node, OMX_INDEXTYPE index, 52 void *params, size_t size); 53 54 virtual status_t setParameter( 55 node_id node, OMX_INDEXTYPE index, 56 const void *params, size_t size); 57 58 virtual status_t getConfig( 59 node_id node, OMX_INDEXTYPE index, 60 void *params, size_t size); 61 62 virtual status_t setConfig( 63 node_id node, OMX_INDEXTYPE index, 64 const void *params, size_t size); 65 66 virtual status_t getState( 67 node_id node, OMX_STATETYPE* state); 68 69 virtual status_t storeMetaDataInBuffers( 70 node_id node, OMX_U32 port_index, OMX_BOOL enable); 71 72 virtual status_t enableGraphicBuffers( 73 node_id node, OMX_U32 port_index, OMX_BOOL enable); 74 75 virtual status_t getGraphicBufferUsage( 76 node_id node, OMX_U32 port_index, OMX_U32* usage); 77 78 virtual status_t useBuffer( 79 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 80 buffer_id *buffer); 81 82 virtual status_t useGraphicBuffer( 83 node_id node, OMX_U32 port_index, 84 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer); 85 86 virtual status_t allocateBuffer( 87 node_id node, OMX_U32 port_index, size_t size, 88 buffer_id *buffer, void **buffer_data); 89 90 virtual status_t allocateBufferWithBackup( 91 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 92 buffer_id *buffer); 93 94 virtual status_t freeBuffer( 95 node_id node, OMX_U32 port_index, buffer_id buffer); 96 97 virtual status_t fillBuffer(node_id node, buffer_id buffer); 98 99 virtual status_t emptyBuffer( 100 node_id node, 101 buffer_id buffer, 102 OMX_U32 range_offset, OMX_U32 range_length, 103 OMX_U32 flags, OMX_TICKS timestamp); 104 105 virtual status_t getExtensionIndex( 106 node_id node, 107 const char *parameter_name, 108 OMX_INDEXTYPE *index); 109 110private: 111 mutable Mutex mLock; 112 113 sp<IOMX> mRemoteOMX; 114 sp<IOMX> mLocalOMX; 115 116 KeyedVector<node_id, bool> mIsLocalNode; 117 118 bool isLocalNode(node_id node) const; 119 bool isLocalNode_l(node_id node) const; 120 const sp<IOMX> &getOMX(node_id node) const; 121 const sp<IOMX> &getOMX_l(node_id node) const; 122 123 static bool IsSoftwareComponent(const char *name); 124 125 DISALLOW_EVIL_CONSTRUCTORS(MuxOMX); 126}; 127 128MuxOMX::MuxOMX(const sp<IOMX> &remoteOMX) 129 : mRemoteOMX(remoteOMX) { 130} 131 132MuxOMX::~MuxOMX() { 133} 134 135bool MuxOMX::isLocalNode(node_id node) const { 136 Mutex::Autolock autoLock(mLock); 137 138 return isLocalNode_l(node); 139} 140 141bool MuxOMX::isLocalNode_l(node_id node) const { 142 return mIsLocalNode.indexOfKey(node) >= 0; 143} 144 145// static 146bool MuxOMX::IsSoftwareComponent(const char *name) { 147 return !strncasecmp(name, "OMX.google.", 11); 148} 149 150const sp<IOMX> &MuxOMX::getOMX(node_id node) const { 151 return isLocalNode(node) ? mLocalOMX : mRemoteOMX; 152} 153 154const sp<IOMX> &MuxOMX::getOMX_l(node_id node) const { 155 return isLocalNode_l(node) ? mLocalOMX : mRemoteOMX; 156} 157 158bool MuxOMX::livesLocally(pid_t pid) { 159 return true; 160} 161 162status_t MuxOMX::listNodes(List<ComponentInfo> *list) { 163 Mutex::Autolock autoLock(mLock); 164 165 if (mLocalOMX == NULL) { 166 mLocalOMX = new OMX; 167 } 168 169 return mLocalOMX->listNodes(list); 170} 171 172status_t MuxOMX::allocateNode( 173 const char *name, const sp<IOMXObserver> &observer, 174 node_id *node) { 175 Mutex::Autolock autoLock(mLock); 176 177 sp<IOMX> omx; 178 179 if (IsSoftwareComponent(name)) { 180 if (mLocalOMX == NULL) { 181 mLocalOMX = new OMX; 182 } 183 omx = mLocalOMX; 184 } else { 185 omx = mRemoteOMX; 186 } 187 188 status_t err = omx->allocateNode(name, observer, node); 189 190 if (err != OK) { 191 return err; 192 } 193 194 if (omx == mLocalOMX) { 195 mIsLocalNode.add(*node, true); 196 } 197 198 return OK; 199} 200 201status_t MuxOMX::freeNode(node_id node) { 202 Mutex::Autolock autoLock(mLock); 203 204 status_t err = getOMX_l(node)->freeNode(node); 205 206 if (err != OK) { 207 return err; 208 } 209 210 mIsLocalNode.removeItem(node); 211 212 return OK; 213} 214 215status_t MuxOMX::sendCommand( 216 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { 217 return getOMX(node)->sendCommand(node, cmd, param); 218} 219 220status_t MuxOMX::getParameter( 221 node_id node, OMX_INDEXTYPE index, 222 void *params, size_t size) { 223 return getOMX(node)->getParameter(node, index, params, size); 224} 225 226status_t MuxOMX::setParameter( 227 node_id node, OMX_INDEXTYPE index, 228 const void *params, size_t size) { 229 return getOMX(node)->setParameter(node, index, params, size); 230} 231 232status_t MuxOMX::getConfig( 233 node_id node, OMX_INDEXTYPE index, 234 void *params, size_t size) { 235 return getOMX(node)->getConfig(node, index, params, size); 236} 237 238status_t MuxOMX::setConfig( 239 node_id node, OMX_INDEXTYPE index, 240 const void *params, size_t size) { 241 return getOMX(node)->setConfig(node, index, params, size); 242} 243 244status_t MuxOMX::getState( 245 node_id node, OMX_STATETYPE* state) { 246 return getOMX(node)->getState(node, state); 247} 248 249status_t MuxOMX::storeMetaDataInBuffers( 250 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 251 return getOMX(node)->storeMetaDataInBuffers(node, port_index, enable); 252} 253 254status_t MuxOMX::enableGraphicBuffers( 255 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 256 return getOMX(node)->enableGraphicBuffers(node, port_index, enable); 257} 258 259status_t MuxOMX::getGraphicBufferUsage( 260 node_id node, OMX_U32 port_index, OMX_U32* usage) { 261 return getOMX(node)->getGraphicBufferUsage(node, port_index, usage); 262} 263 264status_t MuxOMX::useBuffer( 265 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 266 buffer_id *buffer) { 267 return getOMX(node)->useBuffer(node, port_index, params, buffer); 268} 269 270status_t MuxOMX::useGraphicBuffer( 271 node_id node, OMX_U32 port_index, 272 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { 273 return getOMX(node)->useGraphicBuffer( 274 node, port_index, graphicBuffer, buffer); 275} 276 277status_t MuxOMX::allocateBuffer( 278 node_id node, OMX_U32 port_index, size_t size, 279 buffer_id *buffer, void **buffer_data) { 280 return getOMX(node)->allocateBuffer( 281 node, port_index, size, buffer, buffer_data); 282} 283 284status_t MuxOMX::allocateBufferWithBackup( 285 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 286 buffer_id *buffer) { 287 return getOMX(node)->allocateBufferWithBackup( 288 node, port_index, params, buffer); 289} 290 291status_t MuxOMX::freeBuffer( 292 node_id node, OMX_U32 port_index, buffer_id buffer) { 293 return getOMX(node)->freeBuffer(node, port_index, buffer); 294} 295 296status_t MuxOMX::fillBuffer(node_id node, buffer_id buffer) { 297 return getOMX(node)->fillBuffer(node, buffer); 298} 299 300status_t MuxOMX::emptyBuffer( 301 node_id node, 302 buffer_id buffer, 303 OMX_U32 range_offset, OMX_U32 range_length, 304 OMX_U32 flags, OMX_TICKS timestamp) { 305 return getOMX(node)->emptyBuffer( 306 node, buffer, range_offset, range_length, flags, timestamp); 307} 308 309status_t MuxOMX::getExtensionIndex( 310 node_id node, 311 const char *parameter_name, 312 OMX_INDEXTYPE *index) { 313 return getOMX(node)->getExtensionIndex(node, parameter_name, index); 314} 315 316OMXClient::OMXClient() { 317} 318 319status_t OMXClient::connect() { 320 sp<IServiceManager> sm = defaultServiceManager(); 321 sp<IBinder> binder = sm->getService(String16("media.player")); 322 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 323 324 CHECK(service.get() != NULL); 325 326 mOMX = service->getOMX(); 327 CHECK(mOMX.get() != NULL); 328 329 if (!mOMX->livesLocally(getpid())) { 330 ALOGI("Using client-side OMX mux."); 331 mOMX = new MuxOMX(mOMX); 332 } 333 334 return OK; 335} 336 337void OMXClient::disconnect() { 338} 339 340} // namespace android 341