OMXClient.cpp revision d0715867861c216e88a4a7523b6da8a3cb128724
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 mRemoteOMX->asBinder().get(); } 36 37 virtual bool livesLocally(node_id node, 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 updateGraphicBufferInMeta( 87 node_id node, OMX_U32 port_index, 88 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer); 89 90 virtual status_t createInputSurface( 91 node_id node, OMX_U32 port_index, 92 sp<IGraphicBufferProducer> *bufferProducer); 93 94 virtual status_t signalEndOfInputStream(node_id node); 95 96 virtual status_t allocateBuffer( 97 node_id node, OMX_U32 port_index, size_t size, 98 buffer_id *buffer, void **buffer_data); 99 100 virtual status_t allocateBufferWithBackup( 101 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 102 buffer_id *buffer); 103 104 virtual status_t freeBuffer( 105 node_id node, OMX_U32 port_index, buffer_id buffer); 106 107 virtual status_t fillBuffer(node_id node, buffer_id buffer); 108 109 virtual status_t emptyBuffer( 110 node_id node, 111 buffer_id buffer, 112 OMX_U32 range_offset, OMX_U32 range_length, 113 OMX_U32 flags, OMX_TICKS timestamp); 114 115 virtual status_t getExtensionIndex( 116 node_id node, 117 const char *parameter_name, 118 OMX_INDEXTYPE *index); 119 120 virtual status_t setInternalOption( 121 node_id node, 122 OMX_U32 port_index, 123 InternalOptionType type, 124 const void *data, 125 size_t size); 126 127private: 128 mutable Mutex mLock; 129 130 sp<IOMX> mRemoteOMX; 131 sp<IOMX> mLocalOMX; 132 133 KeyedVector<node_id, bool> mIsLocalNode; 134 135 bool isLocalNode(node_id node) const; 136 bool isLocalNode_l(node_id node) const; 137 const sp<IOMX> &getOMX(node_id node) const; 138 const sp<IOMX> &getOMX_l(node_id node) const; 139 140 static bool IsSoftwareComponent(const char *name); 141 142 DISALLOW_EVIL_CONSTRUCTORS(MuxOMX); 143}; 144 145MuxOMX::MuxOMX(const sp<IOMX> &remoteOMX) 146 : mRemoteOMX(remoteOMX) { 147} 148 149MuxOMX::~MuxOMX() { 150} 151 152bool MuxOMX::isLocalNode(node_id node) const { 153 Mutex::Autolock autoLock(mLock); 154 155 return isLocalNode_l(node); 156} 157 158bool MuxOMX::isLocalNode_l(node_id node) const { 159 return mIsLocalNode.indexOfKey(node) >= 0; 160} 161 162// static 163bool MuxOMX::IsSoftwareComponent(const char *name) { 164 return !strncasecmp(name, "OMX.google.", 11); 165} 166 167const sp<IOMX> &MuxOMX::getOMX(node_id node) const { 168 return isLocalNode(node) ? mLocalOMX : mRemoteOMX; 169} 170 171const sp<IOMX> &MuxOMX::getOMX_l(node_id node) const { 172 return isLocalNode_l(node) ? mLocalOMX : mRemoteOMX; 173} 174 175bool MuxOMX::livesLocally(node_id node, pid_t pid) { 176 return getOMX(node)->livesLocally(node, pid); 177} 178 179status_t MuxOMX::listNodes(List<ComponentInfo> *list) { 180 Mutex::Autolock autoLock(mLock); 181 182 if (mLocalOMX == NULL) { 183 mLocalOMX = new OMX; 184 } 185 186 return mLocalOMX->listNodes(list); 187} 188 189status_t MuxOMX::allocateNode( 190 const char *name, const sp<IOMXObserver> &observer, 191 node_id *node) { 192 Mutex::Autolock autoLock(mLock); 193 194 sp<IOMX> omx; 195 196 if (IsSoftwareComponent(name)) { 197 if (mLocalOMX == NULL) { 198 mLocalOMX = new OMX; 199 } 200 omx = mLocalOMX; 201 } else { 202 omx = mRemoteOMX; 203 } 204 205 status_t err = omx->allocateNode(name, observer, node); 206 207 if (err != OK) { 208 return err; 209 } 210 211 if (omx == mLocalOMX) { 212 mIsLocalNode.add(*node, true); 213 } 214 215 return OK; 216} 217 218status_t MuxOMX::freeNode(node_id node) { 219 Mutex::Autolock autoLock(mLock); 220 221 status_t err = getOMX_l(node)->freeNode(node); 222 223 if (err != OK) { 224 return err; 225 } 226 227 mIsLocalNode.removeItem(node); 228 229 return OK; 230} 231 232status_t MuxOMX::sendCommand( 233 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { 234 return getOMX(node)->sendCommand(node, cmd, param); 235} 236 237status_t MuxOMX::getParameter( 238 node_id node, OMX_INDEXTYPE index, 239 void *params, size_t size) { 240 return getOMX(node)->getParameter(node, index, params, size); 241} 242 243status_t MuxOMX::setParameter( 244 node_id node, OMX_INDEXTYPE index, 245 const void *params, size_t size) { 246 return getOMX(node)->setParameter(node, index, params, size); 247} 248 249status_t MuxOMX::getConfig( 250 node_id node, OMX_INDEXTYPE index, 251 void *params, size_t size) { 252 return getOMX(node)->getConfig(node, index, params, size); 253} 254 255status_t MuxOMX::setConfig( 256 node_id node, OMX_INDEXTYPE index, 257 const void *params, size_t size) { 258 return getOMX(node)->setConfig(node, index, params, size); 259} 260 261status_t MuxOMX::getState( 262 node_id node, OMX_STATETYPE* state) { 263 return getOMX(node)->getState(node, state); 264} 265 266status_t MuxOMX::storeMetaDataInBuffers( 267 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 268 return getOMX(node)->storeMetaDataInBuffers(node, port_index, enable); 269} 270 271status_t MuxOMX::enableGraphicBuffers( 272 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 273 return getOMX(node)->enableGraphicBuffers(node, port_index, enable); 274} 275 276status_t MuxOMX::getGraphicBufferUsage( 277 node_id node, OMX_U32 port_index, OMX_U32* usage) { 278 return getOMX(node)->getGraphicBufferUsage(node, port_index, usage); 279} 280 281status_t MuxOMX::useBuffer( 282 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 283 buffer_id *buffer) { 284 return getOMX(node)->useBuffer(node, port_index, params, buffer); 285} 286 287status_t MuxOMX::useGraphicBuffer( 288 node_id node, OMX_U32 port_index, 289 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { 290 return getOMX(node)->useGraphicBuffer( 291 node, port_index, graphicBuffer, buffer); 292} 293 294status_t MuxOMX::updateGraphicBufferInMeta( 295 node_id node, OMX_U32 port_index, 296 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { 297 return getOMX(node)->updateGraphicBufferInMeta( 298 node, port_index, graphicBuffer, buffer); 299} 300 301status_t MuxOMX::createInputSurface( 302 node_id node, OMX_U32 port_index, 303 sp<IGraphicBufferProducer> *bufferProducer) { 304 status_t err = getOMX(node)->createInputSurface( 305 node, port_index, bufferProducer); 306 return err; 307} 308 309status_t MuxOMX::signalEndOfInputStream(node_id node) { 310 return getOMX(node)->signalEndOfInputStream(node); 311} 312 313status_t MuxOMX::allocateBuffer( 314 node_id node, OMX_U32 port_index, size_t size, 315 buffer_id *buffer, void **buffer_data) { 316 return getOMX(node)->allocateBuffer( 317 node, port_index, size, buffer, buffer_data); 318} 319 320status_t MuxOMX::allocateBufferWithBackup( 321 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 322 buffer_id *buffer) { 323 return getOMX(node)->allocateBufferWithBackup( 324 node, port_index, params, buffer); 325} 326 327status_t MuxOMX::freeBuffer( 328 node_id node, OMX_U32 port_index, buffer_id buffer) { 329 return getOMX(node)->freeBuffer(node, port_index, buffer); 330} 331 332status_t MuxOMX::fillBuffer(node_id node, buffer_id buffer) { 333 return getOMX(node)->fillBuffer(node, buffer); 334} 335 336status_t MuxOMX::emptyBuffer( 337 node_id node, 338 buffer_id buffer, 339 OMX_U32 range_offset, OMX_U32 range_length, 340 OMX_U32 flags, OMX_TICKS timestamp) { 341 return getOMX(node)->emptyBuffer( 342 node, buffer, range_offset, range_length, flags, timestamp); 343} 344 345status_t MuxOMX::getExtensionIndex( 346 node_id node, 347 const char *parameter_name, 348 OMX_INDEXTYPE *index) { 349 return getOMX(node)->getExtensionIndex(node, parameter_name, index); 350} 351 352status_t MuxOMX::setInternalOption( 353 node_id node, 354 OMX_U32 port_index, 355 InternalOptionType type, 356 const void *data, 357 size_t size) { 358 return getOMX(node)->setInternalOption(node, port_index, type, data, size); 359} 360 361OMXClient::OMXClient() { 362} 363 364status_t OMXClient::connect() { 365 sp<IServiceManager> sm = defaultServiceManager(); 366 sp<IBinder> binder = sm->getService(String16("media.player")); 367 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 368 369 CHECK(service.get() != NULL); 370 371 mOMX = service->getOMX(); 372 CHECK(mOMX.get() != NULL); 373 374 if (!mOMX->livesLocally(NULL /* node */, getpid())) { 375 ALOGI("Using client-side OMX mux."); 376 mOMX = new MuxOMX(mOMX); 377 } 378 379 return OK; 380} 381 382void OMXClient::disconnect() { 383 if (mOMX.get() != NULL) { 384 mOMX.clear(); 385 mOMX = NULL; 386 } 387} 388 389} // namespace android 390