OMXClient.cpp revision d291c222357303b9611cab89d0c3b047584ef377
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 20#ifdef __LP64__ 21#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS 22#endif 23 24#include <utils/Log.h> 25 26#include <binder/IServiceManager.h> 27#include <media/IMediaPlayerService.h> 28#include <media/stagefright/foundation/ADebug.h> 29#include <media/stagefright/OMXClient.h> 30#include <utils/KeyedVector.h> 31 32#include "include/OMX.h" 33 34namespace android { 35 36struct MuxOMX : public IOMX { 37 MuxOMX(const sp<IOMX> &remoteOMX); 38 virtual ~MuxOMX(); 39 40 virtual IBinder *onAsBinder() { return IInterface::asBinder(mRemoteOMX).get(); } 41 42 virtual bool livesLocally(node_id node, pid_t pid); 43 44 virtual status_t listNodes(List<ComponentInfo> *list); 45 46 virtual status_t allocateNode( 47 const char *name, const sp<IOMXObserver> &observer, 48 node_id *node); 49 50 virtual status_t freeNode(node_id node); 51 52 virtual status_t sendCommand( 53 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param); 54 55 virtual status_t getParameter( 56 node_id node, OMX_INDEXTYPE index, 57 void *params, size_t size); 58 59 virtual status_t setParameter( 60 node_id node, OMX_INDEXTYPE index, 61 const void *params, size_t size); 62 63 virtual status_t getConfig( 64 node_id node, OMX_INDEXTYPE index, 65 void *params, size_t size); 66 67 virtual status_t setConfig( 68 node_id node, OMX_INDEXTYPE index, 69 const void *params, size_t size); 70 71 virtual status_t getState( 72 node_id node, OMX_STATETYPE* state); 73 74 virtual status_t storeMetaDataInBuffers( 75 node_id node, OMX_U32 port_index, OMX_BOOL enable); 76 77 virtual status_t prepareForAdaptivePlayback( 78 node_id node, OMX_U32 port_index, OMX_BOOL enable, 79 OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight); 80 81 virtual status_t configureVideoTunnelMode( 82 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, 83 OMX_U32 audioHwSync, native_handle_t **sidebandHandle); 84 85 virtual status_t enableGraphicBuffers( 86 node_id node, OMX_U32 port_index, OMX_BOOL enable); 87 88 virtual status_t getGraphicBufferUsage( 89 node_id node, OMX_U32 port_index, OMX_U32* usage); 90 91 virtual status_t useBuffer( 92 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 93 buffer_id *buffer); 94 95 virtual status_t useGraphicBuffer( 96 node_id node, OMX_U32 port_index, 97 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer); 98 99 virtual status_t updateGraphicBufferInMeta( 100 node_id node, OMX_U32 port_index, 101 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer); 102 103 virtual status_t createInputSurface( 104 node_id node, OMX_U32 port_index, 105 sp<IGraphicBufferProducer> *bufferProducer); 106 107 virtual status_t createPersistentInputSurface( 108 sp<IGraphicBufferProducer> *bufferProducer, 109 sp<IGraphicBufferConsumer> *bufferConsumer); 110 111 virtual status_t usePersistentInputSurface( 112 node_id node, OMX_U32 port_index, 113 const sp<IGraphicBufferConsumer> &bufferConsumer); 114 115 virtual status_t signalEndOfInputStream(node_id node); 116 117 virtual status_t allocateBuffer( 118 node_id node, OMX_U32 port_index, size_t size, 119 buffer_id *buffer, void **buffer_data); 120 121 virtual status_t allocateBufferWithBackup( 122 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 123 buffer_id *buffer); 124 125 virtual status_t freeBuffer( 126 node_id node, OMX_U32 port_index, buffer_id buffer); 127 128 virtual status_t fillBuffer(node_id node, buffer_id buffer); 129 130 virtual status_t emptyBuffer( 131 node_id node, 132 buffer_id buffer, 133 OMX_U32 range_offset, OMX_U32 range_length, 134 OMX_U32 flags, OMX_TICKS timestamp); 135 136 virtual status_t getExtensionIndex( 137 node_id node, 138 const char *parameter_name, 139 OMX_INDEXTYPE *index); 140 141 virtual status_t setInternalOption( 142 node_id node, 143 OMX_U32 port_index, 144 InternalOptionType type, 145 const void *data, 146 size_t size); 147 148private: 149 mutable Mutex mLock; 150 151 sp<IOMX> mRemoteOMX; 152 sp<IOMX> mLocalOMX; 153 154 KeyedVector<node_id, bool> mIsLocalNode; 155 156 bool isLocalNode(node_id node) const; 157 bool isLocalNode_l(node_id node) const; 158 const sp<IOMX> &getOMX(node_id node) const; 159 const sp<IOMX> &getOMX_l(node_id node) const; 160 161 static bool CanLiveLocally(const char *name); 162 163 DISALLOW_EVIL_CONSTRUCTORS(MuxOMX); 164}; 165 166MuxOMX::MuxOMX(const sp<IOMX> &remoteOMX) 167 : mRemoteOMX(remoteOMX) { 168} 169 170MuxOMX::~MuxOMX() { 171} 172 173bool MuxOMX::isLocalNode(node_id node) const { 174 Mutex::Autolock autoLock(mLock); 175 176 return isLocalNode_l(node); 177} 178 179bool MuxOMX::isLocalNode_l(node_id node) const { 180 return mIsLocalNode.indexOfKey(node) >= 0; 181} 182 183// static 184bool MuxOMX::CanLiveLocally(const char *name) { 185#ifdef __LP64__ 186 (void)name; // disable unused parameter warning 187 // 64 bit processes always run OMX remote on MediaServer 188 return false; 189#else 190 // 32 bit processes run only OMX.google.* components locally 191 return !strncasecmp(name, "OMX.google.", 11); 192#endif 193} 194 195const sp<IOMX> &MuxOMX::getOMX(node_id node) const { 196 return isLocalNode(node) ? mLocalOMX : mRemoteOMX; 197} 198 199const sp<IOMX> &MuxOMX::getOMX_l(node_id node) const { 200 return isLocalNode_l(node) ? mLocalOMX : mRemoteOMX; 201} 202 203bool MuxOMX::livesLocally(node_id node, pid_t pid) { 204 return getOMX(node)->livesLocally(node, pid); 205} 206 207status_t MuxOMX::listNodes(List<ComponentInfo> *list) { 208 Mutex::Autolock autoLock(mLock); 209 210 if (mLocalOMX == NULL) { 211 mLocalOMX = new OMX; 212 } 213 214 return mLocalOMX->listNodes(list); 215} 216 217status_t MuxOMX::allocateNode( 218 const char *name, const sp<IOMXObserver> &observer, 219 node_id *node) { 220 Mutex::Autolock autoLock(mLock); 221 222 sp<IOMX> omx; 223 224 if (CanLiveLocally(name)) { 225 if (mLocalOMX == NULL) { 226 mLocalOMX = new OMX; 227 } 228 omx = mLocalOMX; 229 } else { 230 omx = mRemoteOMX; 231 } 232 233 status_t err = omx->allocateNode(name, observer, node); 234 235 if (err != OK) { 236 return err; 237 } 238 239 if (omx == mLocalOMX) { 240 mIsLocalNode.add(*node, true); 241 } 242 243 return OK; 244} 245 246status_t MuxOMX::freeNode(node_id node) { 247 Mutex::Autolock autoLock(mLock); 248 249 status_t err = getOMX_l(node)->freeNode(node); 250 251 if (err != OK) { 252 return err; 253 } 254 255 mIsLocalNode.removeItem(node); 256 257 return OK; 258} 259 260status_t MuxOMX::sendCommand( 261 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { 262 return getOMX(node)->sendCommand(node, cmd, param); 263} 264 265status_t MuxOMX::getParameter( 266 node_id node, OMX_INDEXTYPE index, 267 void *params, size_t size) { 268 return getOMX(node)->getParameter(node, index, params, size); 269} 270 271status_t MuxOMX::setParameter( 272 node_id node, OMX_INDEXTYPE index, 273 const void *params, size_t size) { 274 return getOMX(node)->setParameter(node, index, params, size); 275} 276 277status_t MuxOMX::getConfig( 278 node_id node, OMX_INDEXTYPE index, 279 void *params, size_t size) { 280 return getOMX(node)->getConfig(node, index, params, size); 281} 282 283status_t MuxOMX::setConfig( 284 node_id node, OMX_INDEXTYPE index, 285 const void *params, size_t size) { 286 return getOMX(node)->setConfig(node, index, params, size); 287} 288 289status_t MuxOMX::getState( 290 node_id node, OMX_STATETYPE* state) { 291 return getOMX(node)->getState(node, state); 292} 293 294status_t MuxOMX::storeMetaDataInBuffers( 295 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 296 return getOMX(node)->storeMetaDataInBuffers(node, port_index, enable); 297} 298 299status_t MuxOMX::prepareForAdaptivePlayback( 300 node_id node, OMX_U32 port_index, OMX_BOOL enable, 301 OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) { 302 return getOMX(node)->prepareForAdaptivePlayback( 303 node, port_index, enable, maxFrameWidth, maxFrameHeight); 304} 305 306status_t MuxOMX::configureVideoTunnelMode( 307 node_id node, OMX_U32 portIndex, OMX_BOOL enable, 308 OMX_U32 audioHwSync, native_handle_t **sidebandHandle) { 309 return getOMX(node)->configureVideoTunnelMode( 310 node, portIndex, enable, audioHwSync, sidebandHandle); 311} 312 313status_t MuxOMX::enableGraphicBuffers( 314 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 315 return getOMX(node)->enableGraphicBuffers(node, port_index, enable); 316} 317 318status_t MuxOMX::getGraphicBufferUsage( 319 node_id node, OMX_U32 port_index, OMX_U32* usage) { 320 return getOMX(node)->getGraphicBufferUsage(node, port_index, usage); 321} 322 323status_t MuxOMX::useBuffer( 324 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 325 buffer_id *buffer) { 326 return getOMX(node)->useBuffer(node, port_index, params, buffer); 327} 328 329status_t MuxOMX::useGraphicBuffer( 330 node_id node, OMX_U32 port_index, 331 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { 332 return getOMX(node)->useGraphicBuffer( 333 node, port_index, graphicBuffer, buffer); 334} 335 336status_t MuxOMX::updateGraphicBufferInMeta( 337 node_id node, OMX_U32 port_index, 338 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { 339 return getOMX(node)->updateGraphicBufferInMeta( 340 node, port_index, graphicBuffer, buffer); 341} 342 343status_t MuxOMX::createInputSurface( 344 node_id node, OMX_U32 port_index, 345 sp<IGraphicBufferProducer> *bufferProducer) { 346 status_t err = getOMX(node)->createInputSurface( 347 node, port_index, bufferProducer); 348 return err; 349} 350 351status_t MuxOMX::createPersistentInputSurface( 352 sp<IGraphicBufferProducer> *bufferProducer, 353 sp<IGraphicBufferConsumer> *bufferConsumer) { 354 // TODO: local or remote? Always use remote for now 355 return mRemoteOMX->createPersistentInputSurface( 356 bufferProducer, bufferConsumer); 357} 358 359status_t MuxOMX::usePersistentInputSurface( 360 node_id node, OMX_U32 port_index, 361 const sp<IGraphicBufferConsumer> &bufferConsumer) { 362 return getOMX(node)->usePersistentInputSurface( 363 node, port_index, bufferConsumer); 364} 365 366status_t MuxOMX::signalEndOfInputStream(node_id node) { 367 return getOMX(node)->signalEndOfInputStream(node); 368} 369 370status_t MuxOMX::allocateBuffer( 371 node_id node, OMX_U32 port_index, size_t size, 372 buffer_id *buffer, void **buffer_data) { 373 return getOMX(node)->allocateBuffer( 374 node, port_index, size, buffer, buffer_data); 375} 376 377status_t MuxOMX::allocateBufferWithBackup( 378 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 379 buffer_id *buffer) { 380 return getOMX(node)->allocateBufferWithBackup( 381 node, port_index, params, buffer); 382} 383 384status_t MuxOMX::freeBuffer( 385 node_id node, OMX_U32 port_index, buffer_id buffer) { 386 return getOMX(node)->freeBuffer(node, port_index, buffer); 387} 388 389status_t MuxOMX::fillBuffer(node_id node, buffer_id buffer) { 390 return getOMX(node)->fillBuffer(node, buffer); 391} 392 393status_t MuxOMX::emptyBuffer( 394 node_id node, 395 buffer_id buffer, 396 OMX_U32 range_offset, OMX_U32 range_length, 397 OMX_U32 flags, OMX_TICKS timestamp) { 398 return getOMX(node)->emptyBuffer( 399 node, buffer, range_offset, range_length, flags, timestamp); 400} 401 402status_t MuxOMX::getExtensionIndex( 403 node_id node, 404 const char *parameter_name, 405 OMX_INDEXTYPE *index) { 406 return getOMX(node)->getExtensionIndex(node, parameter_name, index); 407} 408 409status_t MuxOMX::setInternalOption( 410 node_id node, 411 OMX_U32 port_index, 412 InternalOptionType type, 413 const void *data, 414 size_t size) { 415 return getOMX(node)->setInternalOption(node, port_index, type, data, size); 416} 417 418OMXClient::OMXClient() { 419} 420 421status_t OMXClient::connect() { 422 sp<IServiceManager> sm = defaultServiceManager(); 423 sp<IBinder> binder = sm->getService(String16("media.player")); 424 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 425 426 if (service.get() == NULL) { 427 ALOGE("Cannot obtain IMediaPlayerService"); 428 return NO_INIT; 429 } 430 431 mOMX = service->getOMX(); 432 if (mOMX.get() == NULL) { 433 ALOGE("Cannot obtain IOMX"); 434 return NO_INIT; 435 } 436 437 if (!mOMX->livesLocally(0 /* node */, getpid())) { 438 ALOGI("Using client-side OMX mux."); 439 mOMX = new MuxOMX(mOMX); 440 } 441 442 return OK; 443} 444 445void OMXClient::disconnect() { 446 if (mOMX.get() != NULL) { 447 mOMX.clear(); 448 mOMX = NULL; 449 } 450} 451 452} // namespace android 453