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