Home | History | Annotate | Download | only in libmedia
      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 "IOMX"
     19 #include <utils/Log.h>
     20 
     21 #include <binder/IMemory.h>
     22 #include <binder/Parcel.h>
     23 #include <media/IOMX.h>
     24 #include <media/stagefright/foundation/ADebug.h>
     25 
     26 namespace android {
     27 
     28 enum {
     29     CONNECT = IBinder::FIRST_CALL_TRANSACTION,
     30     LIVES_LOCALLY,
     31     LIST_NODES,
     32     ALLOCATE_NODE,
     33     FREE_NODE,
     34     SEND_COMMAND,
     35     GET_PARAMETER,
     36     SET_PARAMETER,
     37     GET_CONFIG,
     38     SET_CONFIG,
     39     GET_STATE,
     40     ENABLE_GRAPHIC_BUFFERS,
     41     USE_BUFFER,
     42     USE_GRAPHIC_BUFFER,
     43     CREATE_INPUT_SURFACE,
     44     CREATE_PERSISTENT_INPUT_SURFACE,
     45     SET_INPUT_SURFACE,
     46     SIGNAL_END_OF_INPUT_STREAM,
     47     STORE_META_DATA_IN_BUFFERS,
     48     PREPARE_FOR_ADAPTIVE_PLAYBACK,
     49     ALLOC_BUFFER,
     50     ALLOC_BUFFER_WITH_BACKUP,
     51     FREE_BUFFER,
     52     FILL_BUFFER,
     53     EMPTY_BUFFER,
     54     GET_EXTENSION_INDEX,
     55     OBSERVER_ON_MSG,
     56     GET_GRAPHIC_BUFFER_USAGE,
     57     SET_INTERNAL_OPTION,
     58     UPDATE_GRAPHIC_BUFFER_IN_META,
     59     CONFIGURE_VIDEO_TUNNEL_MODE,
     60 };
     61 
     62 class BpOMX : public BpInterface<IOMX> {
     63 public:
     64     BpOMX(const sp<IBinder> &impl)
     65         : BpInterface<IOMX>(impl) {
     66     }
     67 
     68     virtual bool livesLocally(node_id node, pid_t pid) {
     69         Parcel data, reply;
     70         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
     71         data.writeInt32((int32_t)node);
     72         data.writeInt32(pid);
     73         remote()->transact(LIVES_LOCALLY, data, &reply);
     74 
     75         return reply.readInt32() != 0;
     76     }
     77 
     78     virtual status_t listNodes(List<ComponentInfo> *list) {
     79         list->clear();
     80 
     81         Parcel data, reply;
     82         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
     83         remote()->transact(LIST_NODES, data, &reply);
     84 
     85         int32_t n = reply.readInt32();
     86         for (int32_t i = 0; i < n; ++i) {
     87             list->push_back(ComponentInfo());
     88             ComponentInfo &info = *--list->end();
     89 
     90             info.mName = reply.readString8();
     91             int32_t numRoles = reply.readInt32();
     92             for (int32_t j = 0; j < numRoles; ++j) {
     93                 info.mRoles.push_back(reply.readString8());
     94             }
     95         }
     96 
     97         return OK;
     98     }
     99 
    100     virtual status_t allocateNode(
    101             const char *name, const sp<IOMXObserver> &observer, node_id *node) {
    102         Parcel data, reply;
    103         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    104         data.writeCString(name);
    105         data.writeStrongBinder(IInterface::asBinder(observer));
    106         remote()->transact(ALLOCATE_NODE, data, &reply);
    107 
    108         status_t err = reply.readInt32();
    109         if (err == OK) {
    110             *node = (node_id)reply.readInt32();
    111         } else {
    112             *node = 0;
    113         }
    114 
    115         return err;
    116     }
    117 
    118     virtual status_t freeNode(node_id node) {
    119         Parcel data, reply;
    120         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    121         data.writeInt32((int32_t)node);
    122         remote()->transact(FREE_NODE, data, &reply);
    123 
    124         return reply.readInt32();
    125     }
    126 
    127     virtual status_t sendCommand(
    128             node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
    129         Parcel data, reply;
    130         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    131         data.writeInt32((int32_t)node);
    132         data.writeInt32(cmd);
    133         data.writeInt32(param);
    134         remote()->transact(SEND_COMMAND, data, &reply);
    135 
    136         return reply.readInt32();
    137     }
    138 
    139     virtual status_t getParameter(
    140             node_id node, OMX_INDEXTYPE index,
    141             void *params, size_t size) {
    142         Parcel data, reply;
    143         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    144         data.writeInt32((int32_t)node);
    145         data.writeInt32(index);
    146         data.writeInt64(size);
    147         data.write(params, size);
    148         remote()->transact(GET_PARAMETER, data, &reply);
    149 
    150         status_t err = reply.readInt32();
    151         if (err != OK) {
    152             return err;
    153         }
    154 
    155         reply.read(params, size);
    156 
    157         return OK;
    158     }
    159 
    160     virtual status_t setParameter(
    161             node_id node, OMX_INDEXTYPE index,
    162             const void *params, size_t size) {
    163         Parcel data, reply;
    164         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    165         data.writeInt32((int32_t)node);
    166         data.writeInt32(index);
    167         data.writeInt64(size);
    168         data.write(params, size);
    169         remote()->transact(SET_PARAMETER, data, &reply);
    170 
    171         return reply.readInt32();
    172     }
    173 
    174     virtual status_t getConfig(
    175             node_id node, OMX_INDEXTYPE index,
    176             void *params, size_t size) {
    177         Parcel data, reply;
    178         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    179         data.writeInt32((int32_t)node);
    180         data.writeInt32(index);
    181         data.writeInt64(size);
    182         data.write(params, size);
    183         remote()->transact(GET_CONFIG, data, &reply);
    184 
    185         status_t err = reply.readInt32();
    186         if (err != OK) {
    187             return err;
    188         }
    189 
    190         reply.read(params, size);
    191 
    192         return OK;
    193     }
    194 
    195     virtual status_t setConfig(
    196             node_id node, OMX_INDEXTYPE index,
    197             const void *params, size_t size) {
    198         Parcel data, reply;
    199         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    200         data.writeInt32((int32_t)node);
    201         data.writeInt32(index);
    202         data.writeInt64(size);
    203         data.write(params, size);
    204         remote()->transact(SET_CONFIG, data, &reply);
    205 
    206         return reply.readInt32();
    207     }
    208 
    209     virtual status_t getState(
    210             node_id node, OMX_STATETYPE* state) {
    211         Parcel data, reply;
    212         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    213         data.writeInt32((int32_t)node);
    214         remote()->transact(GET_STATE, data, &reply);
    215 
    216         *state = static_cast<OMX_STATETYPE>(reply.readInt32());
    217         return reply.readInt32();
    218     }
    219 
    220     virtual status_t enableGraphicBuffers(
    221             node_id node, OMX_U32 port_index, OMX_BOOL enable) {
    222         Parcel data, reply;
    223         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    224         data.writeInt32((int32_t)node);
    225         data.writeInt32(port_index);
    226         data.writeInt32((uint32_t)enable);
    227         remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply);
    228 
    229         status_t err = reply.readInt32();
    230         return err;
    231     }
    232 
    233     virtual status_t getGraphicBufferUsage(
    234             node_id node, OMX_U32 port_index, OMX_U32* usage) {
    235         Parcel data, reply;
    236         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    237         data.writeInt32((int32_t)node);
    238         data.writeInt32(port_index);
    239         remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
    240 
    241         status_t err = reply.readInt32();
    242         *usage = reply.readInt32();
    243         return err;
    244     }
    245 
    246     virtual status_t useBuffer(
    247             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
    248             buffer_id *buffer, OMX_U32 allottedSize) {
    249         Parcel data, reply;
    250         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    251         data.writeInt32((int32_t)node);
    252         data.writeInt32(port_index);
    253         data.writeStrongBinder(IInterface::asBinder(params));
    254         data.writeInt32(allottedSize);
    255         remote()->transact(USE_BUFFER, data, &reply);
    256 
    257         status_t err = reply.readInt32();
    258         if (err != OK) {
    259             *buffer = 0;
    260 
    261             return err;
    262         }
    263 
    264         *buffer = (buffer_id)reply.readInt32();
    265 
    266         return err;
    267     }
    268 
    269 
    270     virtual status_t useGraphicBuffer(
    271             node_id node, OMX_U32 port_index,
    272             const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
    273         Parcel data, reply;
    274         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    275         data.writeInt32((int32_t)node);
    276         data.writeInt32(port_index);
    277         data.write(*graphicBuffer);
    278         remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
    279 
    280         status_t err = reply.readInt32();
    281         if (err != OK) {
    282             *buffer = 0;
    283 
    284             return err;
    285         }
    286 
    287         *buffer = (buffer_id)reply.readInt32();
    288 
    289         return err;
    290     }
    291 
    292     virtual status_t updateGraphicBufferInMeta(
    293             node_id node, OMX_U32 port_index,
    294             const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
    295         Parcel data, reply;
    296         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    297         data.writeInt32((int32_t)node);
    298         data.writeInt32(port_index);
    299         data.write(*graphicBuffer);
    300         data.writeInt32((int32_t)buffer);
    301         remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
    302 
    303         status_t err = reply.readInt32();
    304         return err;
    305     }
    306 
    307     virtual status_t createInputSurface(
    308             node_id node, OMX_U32 port_index,
    309             sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
    310         Parcel data, reply;
    311         status_t err;
    312         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    313         data.writeInt32((int32_t)node);
    314         data.writeInt32(port_index);
    315         err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
    316         if (err != OK) {
    317             ALOGW("binder transaction failed: %d", err);
    318             return err;
    319         }
    320 
    321         // read type even if createInputSurface failed
    322         int negotiatedType = reply.readInt32();
    323         if (type != NULL) {
    324             *type = (MetadataBufferType)negotiatedType;
    325         }
    326 
    327         err = reply.readInt32();
    328         if (err != OK) {
    329             return err;
    330         }
    331 
    332         *bufferProducer = IGraphicBufferProducer::asInterface(
    333                 reply.readStrongBinder());
    334 
    335         return err;
    336     }
    337 
    338     virtual status_t createPersistentInputSurface(
    339             sp<IGraphicBufferProducer> *bufferProducer,
    340             sp<IGraphicBufferConsumer> *bufferConsumer) {
    341         Parcel data, reply;
    342         status_t err;
    343         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    344         err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply);
    345         if (err != OK) {
    346             ALOGW("binder transaction failed: %d", err);
    347             return err;
    348         }
    349 
    350         err = reply.readInt32();
    351         if (err != OK) {
    352             return err;
    353         }
    354 
    355         *bufferProducer = IGraphicBufferProducer::asInterface(
    356                 reply.readStrongBinder());
    357         *bufferConsumer = IGraphicBufferConsumer::asInterface(
    358                 reply.readStrongBinder());
    359 
    360         return err;
    361     }
    362 
    363     virtual status_t setInputSurface(
    364             node_id node, OMX_U32 port_index,
    365             const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) {
    366         Parcel data, reply;
    367         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    368         status_t err;
    369         data.writeInt32((int32_t)node);
    370         data.writeInt32(port_index);
    371         data.writeStrongBinder(IInterface::asBinder(bufferConsumer));
    372 
    373         err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
    374 
    375         if (err != OK) {
    376             ALOGW("binder transaction failed: %d", err);
    377             return err;
    378         }
    379 
    380         // read type even if setInputSurface failed
    381         int negotiatedType = reply.readInt32();
    382         if (type != NULL) {
    383             *type = (MetadataBufferType)negotiatedType;
    384         }
    385 
    386         return reply.readInt32();
    387     }
    388 
    389     virtual status_t signalEndOfInputStream(node_id node) {
    390         Parcel data, reply;
    391         status_t err;
    392         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    393         data.writeInt32((int32_t)node);
    394         err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply);
    395         if (err != OK) {
    396             ALOGW("binder transaction failed: %d", err);
    397             return err;
    398         }
    399 
    400         return reply.readInt32();
    401     }
    402 
    403     virtual status_t storeMetaDataInBuffers(
    404             node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
    405         Parcel data, reply;
    406         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    407         data.writeInt32((int32_t)node);
    408         data.writeInt32(port_index);
    409         data.writeInt32((uint32_t)enable);
    410         remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
    411 
    412         // read type even storeMetaDataInBuffers failed
    413         int negotiatedType = reply.readInt32();
    414         if (type != NULL) {
    415             *type = (MetadataBufferType)negotiatedType;
    416         }
    417 
    418         return reply.readInt32();
    419     }
    420 
    421     virtual status_t prepareForAdaptivePlayback(
    422             node_id node, OMX_U32 port_index, OMX_BOOL enable,
    423             OMX_U32 max_width, OMX_U32 max_height) {
    424         Parcel data, reply;
    425         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    426         data.writeInt32((int32_t)node);
    427         data.writeInt32(port_index);
    428         data.writeInt32((int32_t)enable);
    429         data.writeInt32(max_width);
    430         data.writeInt32(max_height);
    431         remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
    432 
    433         status_t err = reply.readInt32();
    434         return err;
    435     }
    436 
    437     virtual status_t configureVideoTunnelMode(
    438             node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
    439             OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
    440         Parcel data, reply;
    441         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    442         data.writeInt32((int32_t)node);
    443         data.writeInt32(portIndex);
    444         data.writeInt32((int32_t)tunneled);
    445         data.writeInt32(audioHwSync);
    446         remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
    447 
    448         status_t err = reply.readInt32();
    449         if (sidebandHandle) {
    450             *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
    451         }
    452         return err;
    453     }
    454 
    455 
    456     virtual status_t allocateBuffer(
    457             node_id node, OMX_U32 port_index, size_t size,
    458             buffer_id *buffer, void **buffer_data) {
    459         Parcel data, reply;
    460         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    461         data.writeInt32((int32_t)node);
    462         data.writeInt32(port_index);
    463         data.writeInt64(size);
    464         remote()->transact(ALLOC_BUFFER, data, &reply);
    465 
    466         status_t err = reply.readInt32();
    467         if (err != OK) {
    468             *buffer = 0;
    469 
    470             return err;
    471         }
    472 
    473         *buffer = (buffer_id)reply.readInt32();
    474         *buffer_data = (void *)reply.readInt64();
    475 
    476         return err;
    477     }
    478 
    479     virtual status_t allocateBufferWithBackup(
    480             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
    481             buffer_id *buffer, OMX_U32 allottedSize) {
    482         Parcel data, reply;
    483         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    484         data.writeInt32((int32_t)node);
    485         data.writeInt32(port_index);
    486         data.writeStrongBinder(IInterface::asBinder(params));
    487         data.writeInt32(allottedSize);
    488         remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
    489 
    490         status_t err = reply.readInt32();
    491         if (err != OK) {
    492             *buffer = 0;
    493 
    494             return err;
    495         }
    496 
    497         *buffer = (buffer_id)reply.readInt32();
    498 
    499         return err;
    500     }
    501 
    502     virtual status_t freeBuffer(
    503             node_id node, OMX_U32 port_index, buffer_id buffer) {
    504         Parcel data, reply;
    505         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    506         data.writeInt32((int32_t)node);
    507         data.writeInt32(port_index);
    508         data.writeInt32((int32_t)buffer);
    509         remote()->transact(FREE_BUFFER, data, &reply);
    510 
    511         return reply.readInt32();
    512     }
    513 
    514     virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
    515         Parcel data, reply;
    516         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    517         data.writeInt32((int32_t)node);
    518         data.writeInt32((int32_t)buffer);
    519         data.writeInt32(fenceFd >= 0);
    520         if (fenceFd >= 0) {
    521             data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
    522         }
    523         remote()->transact(FILL_BUFFER, data, &reply);
    524 
    525         return reply.readInt32();
    526     }
    527 
    528     virtual status_t emptyBuffer(
    529             node_id node,
    530             buffer_id buffer,
    531             OMX_U32 range_offset, OMX_U32 range_length,
    532             OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
    533         Parcel data, reply;
    534         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    535         data.writeInt32((int32_t)node);
    536         data.writeInt32((int32_t)buffer);
    537         data.writeInt32(range_offset);
    538         data.writeInt32(range_length);
    539         data.writeInt32(flags);
    540         data.writeInt64(timestamp);
    541         data.writeInt32(fenceFd >= 0);
    542         if (fenceFd >= 0) {
    543             data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
    544         }
    545         remote()->transact(EMPTY_BUFFER, data, &reply);
    546 
    547         return reply.readInt32();
    548     }
    549 
    550     virtual status_t getExtensionIndex(
    551             node_id node,
    552             const char *parameter_name,
    553             OMX_INDEXTYPE *index) {
    554         Parcel data, reply;
    555         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    556         data.writeInt32((int32_t)node);
    557         data.writeCString(parameter_name);
    558 
    559         remote()->transact(GET_EXTENSION_INDEX, data, &reply);
    560 
    561         status_t err = reply.readInt32();
    562         if (err == OK) {
    563             *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
    564         } else {
    565             *index = OMX_IndexComponentStartUnused;
    566         }
    567 
    568         return err;
    569     }
    570 
    571     virtual status_t setInternalOption(
    572             node_id node,
    573             OMX_U32 port_index,
    574             InternalOptionType type,
    575             const void *optionData,
    576             size_t size) {
    577         Parcel data, reply;
    578         data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
    579         data.writeInt32((int32_t)node);
    580         data.writeInt32(port_index);
    581         data.writeInt64(size);
    582         data.write(optionData, size);
    583         data.writeInt32(type);
    584         remote()->transact(SET_INTERNAL_OPTION, data, &reply);
    585 
    586         return reply.readInt32();
    587     }
    588 };
    589 
    590 IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
    591 
    592 ////////////////////////////////////////////////////////////////////////////////
    593 
    594 #define CHECK_OMX_INTERFACE(interface, data, reply) \
    595         do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
    596             ALOGW("Call incorrectly routed to " #interface); \
    597             return PERMISSION_DENIED; \
    598         } } while (0)
    599 
    600 status_t BnOMX::onTransact(
    601     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
    602     switch (code) {
    603         case LIVES_LOCALLY:
    604         {
    605             CHECK_OMX_INTERFACE(IOMX, data, reply);
    606             node_id node = (node_id)data.readInt32();
    607             pid_t pid = (pid_t)data.readInt32();
    608             reply->writeInt32(livesLocally(node, pid));
    609 
    610             return OK;
    611         }
    612 
    613         case LIST_NODES:
    614         {
    615             CHECK_OMX_INTERFACE(IOMX, data, reply);
    616 
    617             List<ComponentInfo> list;
    618             listNodes(&list);
    619 
    620             reply->writeInt32(list.size());
    621             for (List<ComponentInfo>::iterator it = list.begin();
    622                  it != list.end(); ++it) {
    623                 ComponentInfo &cur = *it;
    624 
    625                 reply->writeString8(cur.mName);
    626                 reply->writeInt32(cur.mRoles.size());
    627                 for (List<String8>::iterator role_it = cur.mRoles.begin();
    628                      role_it != cur.mRoles.end(); ++role_it) {
    629                     reply->writeString8(*role_it);
    630                 }
    631             }
    632 
    633             return NO_ERROR;
    634         }
    635 
    636         case ALLOCATE_NODE:
    637         {
    638             CHECK_OMX_INTERFACE(IOMX, data, reply);
    639 
    640             const char *name = data.readCString();
    641 
    642             sp<IOMXObserver> observer =
    643                 interface_cast<IOMXObserver>(data.readStrongBinder());
    644 
    645             node_id node;
    646 
    647             status_t err = allocateNode(name, observer, &node);
    648             reply->writeInt32(err);
    649             if (err == OK) {
    650                 reply->writeInt32((int32_t)node);
    651             }
    652 
    653             return NO_ERROR;
    654         }
    655 
    656         case FREE_NODE:
    657         {
    658             CHECK_OMX_INTERFACE(IOMX, data, reply);
    659 
    660             node_id node = (node_id)data.readInt32();
    661 
    662             reply->writeInt32(freeNode(node));
    663 
    664             return NO_ERROR;
    665         }
    666 
    667         case SEND_COMMAND:
    668         {
    669             CHECK_OMX_INTERFACE(IOMX, data, reply);
    670 
    671             node_id node = (node_id)data.readInt32();
    672 
    673             OMX_COMMANDTYPE cmd =
    674                 static_cast<OMX_COMMANDTYPE>(data.readInt32());
    675 
    676             OMX_S32 param = data.readInt32();
    677             reply->writeInt32(sendCommand(node, cmd, param));
    678 
    679             return NO_ERROR;
    680         }
    681 
    682         case GET_PARAMETER:
    683         case SET_PARAMETER:
    684         case GET_CONFIG:
    685         case SET_CONFIG:
    686         case SET_INTERNAL_OPTION:
    687         {
    688             CHECK_OMX_INTERFACE(IOMX, data, reply);
    689 
    690             node_id node = (node_id)data.readInt32();
    691             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
    692 
    693             size_t size = data.readInt64();
    694 
    695             void *params = malloc(size);
    696             data.read(params, size);
    697 
    698             status_t err;
    699             switch (code) {
    700                 case GET_PARAMETER:
    701                     err = getParameter(node, index, params, size);
    702                     break;
    703                 case SET_PARAMETER:
    704                     err = setParameter(node, index, params, size);
    705                     break;
    706                 case GET_CONFIG:
    707                     err = getConfig(node, index, params, size);
    708                     break;
    709                 case SET_CONFIG:
    710                     err = setConfig(node, index, params, size);
    711                     break;
    712                 case SET_INTERNAL_OPTION:
    713                 {
    714                     InternalOptionType type =
    715                         (InternalOptionType)data.readInt32();
    716 
    717                     err = setInternalOption(node, index, type, params, size);
    718                     break;
    719                 }
    720 
    721                 default:
    722                     TRESPASS();
    723             }
    724 
    725             reply->writeInt32(err);
    726 
    727             if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
    728                 reply->write(params, size);
    729             }
    730 
    731             free(params);
    732             params = NULL;
    733 
    734             return NO_ERROR;
    735         }
    736 
    737         case GET_STATE:
    738         {
    739             CHECK_OMX_INTERFACE(IOMX, data, reply);
    740 
    741             node_id node = (node_id)data.readInt32();
    742             OMX_STATETYPE state = OMX_StateInvalid;
    743 
    744             status_t err = getState(node, &state);
    745             reply->writeInt32(state);
    746             reply->writeInt32(err);
    747 
    748             return NO_ERROR;
    749         }
    750 
    751         case ENABLE_GRAPHIC_BUFFERS:
    752         {
    753             CHECK_OMX_INTERFACE(IOMX, data, reply);
    754 
    755             node_id node = (node_id)data.readInt32();
    756             OMX_U32 port_index = data.readInt32();
    757             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
    758 
    759             status_t err = enableGraphicBuffers(node, port_index, enable);
    760             reply->writeInt32(err);
    761 
    762             return NO_ERROR;
    763         }
    764 
    765         case GET_GRAPHIC_BUFFER_USAGE:
    766         {
    767             CHECK_OMX_INTERFACE(IOMX, data, reply);
    768 
    769             node_id node = (node_id)data.readInt32();
    770             OMX_U32 port_index = data.readInt32();
    771 
    772             OMX_U32 usage = 0;
    773             status_t err = getGraphicBufferUsage(node, port_index, &usage);
    774             reply->writeInt32(err);
    775             reply->writeInt32(usage);
    776 
    777             return NO_ERROR;
    778         }
    779 
    780         case USE_BUFFER:
    781         {
    782             CHECK_OMX_INTERFACE(IOMX, data, reply);
    783 
    784             node_id node = (node_id)data.readInt32();
    785             OMX_U32 port_index = data.readInt32();
    786             sp<IMemory> params =
    787                 interface_cast<IMemory>(data.readStrongBinder());
    788             OMX_U32 allottedSize = data.readInt32();
    789 
    790             buffer_id buffer;
    791             status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
    792             reply->writeInt32(err);
    793 
    794             if (err == OK) {
    795                 reply->writeInt32((int32_t)buffer);
    796             }
    797 
    798             return NO_ERROR;
    799         }
    800 
    801         case USE_GRAPHIC_BUFFER:
    802         {
    803             CHECK_OMX_INTERFACE(IOMX, data, reply);
    804 
    805             node_id node = (node_id)data.readInt32();
    806             OMX_U32 port_index = data.readInt32();
    807             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
    808             data.read(*graphicBuffer);
    809 
    810             buffer_id buffer;
    811             status_t err = useGraphicBuffer(
    812                     node, port_index, graphicBuffer, &buffer);
    813             reply->writeInt32(err);
    814 
    815             if (err == OK) {
    816                 reply->writeInt32((int32_t)buffer);
    817             }
    818 
    819             return NO_ERROR;
    820         }
    821 
    822         case UPDATE_GRAPHIC_BUFFER_IN_META:
    823         {
    824             CHECK_OMX_INTERFACE(IOMX, data, reply);
    825 
    826             node_id node = (node_id)data.readInt32();
    827             OMX_U32 port_index = data.readInt32();
    828             sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
    829             data.read(*graphicBuffer);
    830             buffer_id buffer = (buffer_id)data.readInt32();
    831 
    832             status_t err = updateGraphicBufferInMeta(
    833                     node, port_index, graphicBuffer, buffer);
    834             reply->writeInt32(err);
    835 
    836             return NO_ERROR;
    837         }
    838 
    839         case CREATE_INPUT_SURFACE:
    840         {
    841             CHECK_OMX_INTERFACE(IOMX, data, reply);
    842 
    843             node_id node = (node_id)data.readInt32();
    844             OMX_U32 port_index = data.readInt32();
    845 
    846             sp<IGraphicBufferProducer> bufferProducer;
    847             MetadataBufferType type;
    848             status_t err = createInputSurface(node, port_index, &bufferProducer, &type);
    849 
    850             reply->writeInt32(type);
    851             reply->writeInt32(err);
    852 
    853             if (err == OK) {
    854                 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
    855             }
    856 
    857             return NO_ERROR;
    858         }
    859 
    860         case CREATE_PERSISTENT_INPUT_SURFACE:
    861         {
    862             CHECK_OMX_INTERFACE(IOMX, data, reply);
    863 
    864             sp<IGraphicBufferProducer> bufferProducer;
    865             sp<IGraphicBufferConsumer> bufferConsumer;
    866             status_t err = createPersistentInputSurface(
    867                     &bufferProducer, &bufferConsumer);
    868 
    869             reply->writeInt32(err);
    870 
    871             if (err == OK) {
    872                 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
    873                 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
    874             }
    875 
    876             return NO_ERROR;
    877         }
    878 
    879         case SET_INPUT_SURFACE:
    880         {
    881             CHECK_OMX_INTERFACE(IOMX, data, reply);
    882 
    883             node_id node = (node_id)data.readInt32();
    884             OMX_U32 port_index = data.readInt32();
    885 
    886             sp<IGraphicBufferConsumer> bufferConsumer =
    887                     interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
    888 
    889             MetadataBufferType type;
    890             status_t err = setInputSurface(node, port_index, bufferConsumer, &type);
    891 
    892             reply->writeInt32(type);
    893             reply->writeInt32(err);
    894             return NO_ERROR;
    895         }
    896 
    897         case SIGNAL_END_OF_INPUT_STREAM:
    898         {
    899             CHECK_OMX_INTERFACE(IOMX, data, reply);
    900 
    901             node_id node = (node_id)data.readInt32();
    902 
    903             status_t err = signalEndOfInputStream(node);
    904             reply->writeInt32(err);
    905 
    906             return NO_ERROR;
    907         }
    908 
    909         case STORE_META_DATA_IN_BUFFERS:
    910         {
    911             CHECK_OMX_INTERFACE(IOMX, data, reply);
    912 
    913             node_id node = (node_id)data.readInt32();
    914             OMX_U32 port_index = data.readInt32();
    915             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
    916 
    917             MetadataBufferType type;
    918             status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
    919             reply->writeInt32(type);
    920             reply->writeInt32(err);
    921 
    922             return NO_ERROR;
    923         }
    924 
    925         case PREPARE_FOR_ADAPTIVE_PLAYBACK:
    926         {
    927             CHECK_OMX_INTERFACE(IOMX, data, reply);
    928 
    929             node_id node = (node_id)data.readInt32();
    930             OMX_U32 port_index = data.readInt32();
    931             OMX_BOOL enable = (OMX_BOOL)data.readInt32();
    932             OMX_U32 max_width = data.readInt32();
    933             OMX_U32 max_height = data.readInt32();
    934 
    935             status_t err = prepareForAdaptivePlayback(
    936                     node, port_index, enable, max_width, max_height);
    937             reply->writeInt32(err);
    938 
    939             return NO_ERROR;
    940         }
    941 
    942         case CONFIGURE_VIDEO_TUNNEL_MODE:
    943         {
    944             CHECK_OMX_INTERFACE(IOMX, data, reply);
    945 
    946             node_id node = (node_id)data.readInt32();
    947             OMX_U32 port_index = data.readInt32();
    948             OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
    949             OMX_U32 audio_hw_sync = data.readInt32();
    950 
    951             native_handle_t *sideband_handle;
    952             status_t err = configureVideoTunnelMode(
    953                     node, port_index, tunneled, audio_hw_sync, &sideband_handle);
    954             reply->writeInt32(err);
    955             reply->writeNativeHandle(sideband_handle);
    956 
    957             return NO_ERROR;
    958         }
    959 
    960         case ALLOC_BUFFER:
    961         {
    962             CHECK_OMX_INTERFACE(IOMX, data, reply);
    963 
    964             node_id node = (node_id)data.readInt32();
    965             OMX_U32 port_index = data.readInt32();
    966             size_t size = data.readInt64();
    967 
    968             buffer_id buffer;
    969             void *buffer_data;
    970             status_t err = allocateBuffer(
    971                     node, port_index, size, &buffer, &buffer_data);
    972             reply->writeInt32(err);
    973 
    974             if (err == OK) {
    975                 reply->writeInt32((int32_t)buffer);
    976                 reply->writeInt64((uintptr_t)buffer_data);
    977             }
    978 
    979             return NO_ERROR;
    980         }
    981 
    982         case ALLOC_BUFFER_WITH_BACKUP:
    983         {
    984             CHECK_OMX_INTERFACE(IOMX, data, reply);
    985 
    986             node_id node = (node_id)data.readInt32();
    987             OMX_U32 port_index = data.readInt32();
    988             sp<IMemory> params =
    989                 interface_cast<IMemory>(data.readStrongBinder());
    990             OMX_U32 allottedSize = data.readInt32();
    991 
    992             buffer_id buffer;
    993             status_t err = allocateBufferWithBackup(
    994                     node, port_index, params, &buffer, allottedSize);
    995 
    996             reply->writeInt32(err);
    997 
    998             if (err == OK) {
    999                 reply->writeInt32((int32_t)buffer);
   1000             }
   1001 
   1002             return NO_ERROR;
   1003         }
   1004 
   1005         case FREE_BUFFER:
   1006         {
   1007             CHECK_OMX_INTERFACE(IOMX, data, reply);
   1008 
   1009             node_id node = (node_id)data.readInt32();
   1010             OMX_U32 port_index = data.readInt32();
   1011             buffer_id buffer = (buffer_id)data.readInt32();
   1012             reply->writeInt32(freeBuffer(node, port_index, buffer));
   1013 
   1014             return NO_ERROR;
   1015         }
   1016 
   1017         case FILL_BUFFER:
   1018         {
   1019             CHECK_OMX_INTERFACE(IOMX, data, reply);
   1020 
   1021             node_id node = (node_id)data.readInt32();
   1022             buffer_id buffer = (buffer_id)data.readInt32();
   1023             bool haveFence = data.readInt32();
   1024             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
   1025             reply->writeInt32(fillBuffer(node, buffer, fenceFd));
   1026 
   1027             return NO_ERROR;
   1028         }
   1029 
   1030         case EMPTY_BUFFER:
   1031         {
   1032             CHECK_OMX_INTERFACE(IOMX, data, reply);
   1033 
   1034             node_id node = (node_id)data.readInt32();
   1035             buffer_id buffer = (buffer_id)data.readInt32();
   1036             OMX_U32 range_offset = data.readInt32();
   1037             OMX_U32 range_length = data.readInt32();
   1038             OMX_U32 flags = data.readInt32();
   1039             OMX_TICKS timestamp = data.readInt64();
   1040             bool haveFence = data.readInt32();
   1041             int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
   1042             reply->writeInt32(emptyBuffer(
   1043                     node, buffer, range_offset, range_length, flags, timestamp, fenceFd));
   1044 
   1045             return NO_ERROR;
   1046         }
   1047 
   1048         case GET_EXTENSION_INDEX:
   1049         {
   1050             CHECK_OMX_INTERFACE(IOMX, data, reply);
   1051 
   1052             node_id node = (node_id)data.readInt32();
   1053             const char *parameter_name = data.readCString();
   1054 
   1055             OMX_INDEXTYPE index;
   1056             status_t err = getExtensionIndex(node, parameter_name, &index);
   1057 
   1058             reply->writeInt32(err);
   1059 
   1060             if (err == OK) {
   1061                 reply->writeInt32(index);
   1062             }
   1063 
   1064             return OK;
   1065         }
   1066 
   1067         default:
   1068             return BBinder::onTransact(code, data, reply, flags);
   1069     }
   1070 }
   1071 
   1072 ////////////////////////////////////////////////////////////////////////////////
   1073 
   1074 class BpOMXObserver : public BpInterface<IOMXObserver> {
   1075 public:
   1076     BpOMXObserver(const sp<IBinder> &impl)
   1077         : BpInterface<IOMXObserver>(impl) {
   1078     }
   1079 
   1080     virtual void onMessages(const std::list<omx_message> &messages) {
   1081         Parcel data, reply;
   1082         std::list<omx_message>::const_iterator it = messages.cbegin();
   1083         bool first = true;
   1084         while (it != messages.cend()) {
   1085             const omx_message &msg = *it++;
   1086             if (first) {
   1087                 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
   1088                 data.writeInt32(msg.node);
   1089                 first = false;
   1090             }
   1091             data.writeInt32(msg.fenceFd >= 0);
   1092             if (msg.fenceFd >= 0) {
   1093                 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
   1094             }
   1095             data.writeInt32(msg.type);
   1096             data.write(&msg.u, sizeof(msg.u));
   1097             ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
   1098         }
   1099         if (!first) {
   1100             data.writeInt32(-1); // mark end
   1101             remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
   1102         }
   1103     }
   1104 };
   1105 
   1106 IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
   1107 
   1108 status_t BnOMXObserver::onTransact(
   1109     uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
   1110     switch (code) {
   1111         case OBSERVER_ON_MSG:
   1112         {
   1113             CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
   1114             IOMX::node_id node = data.readInt32();
   1115             std::list<omx_message> messages;
   1116             status_t err = FAILED_TRANSACTION; // must receive at least one message
   1117             do {
   1118                 int haveFence = data.readInt32();
   1119                 if (haveFence < 0) { // we use -1 to mark end of messages
   1120                     break;
   1121                 }
   1122                 omx_message msg;
   1123                 msg.node = node;
   1124                 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
   1125                 msg.type = (typeof(msg.type))data.readInt32();
   1126                 err = data.read(&msg.u, sizeof(msg.u));
   1127                 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
   1128                 messages.push_back(msg);
   1129             } while (err == OK);
   1130 
   1131             if (err == OK) {
   1132                 onMessages(messages);
   1133             }
   1134 
   1135             return err;
   1136         }
   1137 
   1138         default:
   1139             return BBinder::onTransact(code, data, reply, flags);
   1140     }
   1141 }
   1142 
   1143 }  // namespace android
   1144