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