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