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 34 namespace android { 35 36 struct 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, MetadataBufferType *type); 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, OMX_U32 allottedSize); 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, MetadataBufferType *type); 106 107 virtual status_t createPersistentInputSurface( 108 sp<IGraphicBufferProducer> *bufferProducer, 109 sp<IGraphicBufferConsumer> *bufferConsumer); 110 111 virtual status_t setInputSurface( 112 node_id node, OMX_U32 port_index, 113 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type); 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, OMX_U32 allottedSize); 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, int fenceFd); 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, int fenceFd); 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 148 private: 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 166 MuxOMX::MuxOMX(const sp<IOMX> &remoteOMX) 167 : mRemoteOMX(remoteOMX) { 168 } 169 170 MuxOMX::~MuxOMX() { 171 } 172 173 bool MuxOMX::isLocalNode(node_id node) const { 174 Mutex::Autolock autoLock(mLock); 175 176 return isLocalNode_l(node); 177 } 178 179 bool MuxOMX::isLocalNode_l(node_id node) const { 180 return mIsLocalNode.indexOfKey(node) >= 0; 181 } 182 183 // static 184 bool 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 195 const sp<IOMX> &MuxOMX::getOMX(node_id node) const { 196 return isLocalNode(node) ? mLocalOMX : mRemoteOMX; 197 } 198 199 const sp<IOMX> &MuxOMX::getOMX_l(node_id node) const { 200 return isLocalNode_l(node) ? mLocalOMX : mRemoteOMX; 201 } 202 203 bool MuxOMX::livesLocally(node_id node, pid_t pid) { 204 return getOMX(node)->livesLocally(node, pid); 205 } 206 207 status_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 217 status_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 246 status_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 260 status_t MuxOMX::sendCommand( 261 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { 262 return getOMX(node)->sendCommand(node, cmd, param); 263 } 264 265 status_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 271 status_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 277 status_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 283 status_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 289 status_t MuxOMX::getState( 290 node_id node, OMX_STATETYPE* state) { 291 return getOMX(node)->getState(node, state); 292 } 293 294 status_t MuxOMX::storeMetaDataInBuffers( 295 node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) { 296 return getOMX(node)->storeMetaDataInBuffers(node, port_index, enable, type); 297 } 298 299 status_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 306 status_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 313 status_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 318 status_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 323 status_t MuxOMX::useBuffer( 324 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 325 buffer_id *buffer, OMX_U32 allottedSize) { 326 return getOMX(node)->useBuffer(node, port_index, params, buffer, allottedSize); 327 } 328 329 status_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 336 status_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 343 status_t MuxOMX::createInputSurface( 344 node_id node, OMX_U32 port_index, 345 sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) { 346 status_t err = getOMX(node)->createInputSurface( 347 node, port_index, bufferProducer, type); 348 return err; 349 } 350 351 status_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 359 status_t MuxOMX::setInputSurface( 360 node_id node, OMX_U32 port_index, 361 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) { 362 return getOMX(node)->setInputSurface(node, port_index, bufferConsumer, type); 363 } 364 365 status_t MuxOMX::signalEndOfInputStream(node_id node) { 366 return getOMX(node)->signalEndOfInputStream(node); 367 } 368 369 status_t MuxOMX::allocateBuffer( 370 node_id node, OMX_U32 port_index, size_t size, 371 buffer_id *buffer, void **buffer_data) { 372 return getOMX(node)->allocateBuffer( 373 node, port_index, size, buffer, buffer_data); 374 } 375 376 status_t MuxOMX::allocateBufferWithBackup( 377 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 378 buffer_id *buffer, OMX_U32 allottedSize) { 379 return getOMX(node)->allocateBufferWithBackup( 380 node, port_index, params, buffer, allottedSize); 381 } 382 383 status_t MuxOMX::freeBuffer( 384 node_id node, OMX_U32 port_index, buffer_id buffer) { 385 return getOMX(node)->freeBuffer(node, port_index, buffer); 386 } 387 388 status_t MuxOMX::fillBuffer(node_id node, buffer_id buffer, int fenceFd) { 389 return getOMX(node)->fillBuffer(node, buffer, fenceFd); 390 } 391 392 status_t MuxOMX::emptyBuffer( 393 node_id node, 394 buffer_id buffer, 395 OMX_U32 range_offset, OMX_U32 range_length, 396 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 397 return getOMX(node)->emptyBuffer( 398 node, buffer, range_offset, range_length, flags, timestamp, fenceFd); 399 } 400 401 status_t MuxOMX::getExtensionIndex( 402 node_id node, 403 const char *parameter_name, 404 OMX_INDEXTYPE *index) { 405 return getOMX(node)->getExtensionIndex(node, parameter_name, index); 406 } 407 408 status_t MuxOMX::setInternalOption( 409 node_id node, 410 OMX_U32 port_index, 411 InternalOptionType type, 412 const void *data, 413 size_t size) { 414 return getOMX(node)->setInternalOption(node, port_index, type, data, size); 415 } 416 417 OMXClient::OMXClient() { 418 } 419 420 status_t OMXClient::connect() { 421 sp<IServiceManager> sm = defaultServiceManager(); 422 sp<IBinder> binder = sm->getService(String16("media.player")); 423 sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder); 424 425 if (service.get() == NULL) { 426 ALOGE("Cannot obtain IMediaPlayerService"); 427 return NO_INIT; 428 } 429 430 mOMX = service->getOMX(); 431 if (mOMX.get() == NULL) { 432 ALOGE("Cannot obtain IOMX"); 433 return NO_INIT; 434 } 435 436 if (!mOMX->livesLocally(0 /* node */, getpid())) { 437 ALOGI("Using client-side OMX mux."); 438 mOMX = new MuxOMX(mOMX); 439 } 440 441 return OK; 442 } 443 444 void OMXClient::disconnect() { 445 if (mOMX.get() != NULL) { 446 mOMX.clear(); 447 mOMX = NULL; 448 } 449 } 450 451 } // namespace android 452