Home | History | Annotate | Download | only in libstagefright
      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> &params,
     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> &params,
    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> &params,
    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> &params,
    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