IOMX.cpp revision ac7d4125516299b8a3e6f2b25822a692bdd96311
143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar/*
243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Copyright (c) 2009 The Android Open Source Project
343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar *
443596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * you may not use this file except in compliance with the License.
643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * You may obtain a copy of the License at
743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar *
843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar *     http://www.apache.org/licenses/LICENSE-2.0
943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar *
1043596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * Unless required by applicable law or agreed to in writing, software
1143596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
1243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1343596c2b2997e40b709627419732100d78a62ff0Yigit Boyar * See the License for the specific language governing permissions and
14fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount * limitations under the License.
1543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar */
16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount
1743596c2b2997e40b709627419732100d78a62ff0Yigit Boyar//#define LOG_NDEBUG 0
18e7c2a5e45d7651899790bd347da635875f9c73fbGeorge Mount#define LOG_TAG "IOMX"
19e7c2a5e45d7651899790bd347da635875f9c73fbGeorge Mount#include <utils/Log.h>
204df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar
2196e1c821dd446d1ed78f8ae61131550588f60a24George Mount#include <sys/mman.h>
2296e1c821dd446d1ed78f8ae61131550588f60a24George Mount
236047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <binder/IMemory.h>
246047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <binder/Parcel.h>
2596e1c821dd446d1ed78f8ae61131550588f60a24George Mount#include <media/IOMX.h>
266047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <media/stagefright/foundation/ADebug.h>
27ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount#include <media/openmax/OMX_IndexExt.h>
28ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount#include <media/OMXBuffer.h>
296047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <utils/NativeHandle.h>
306047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <gui/IGraphicBufferProducer.h>
31af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar
32af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar#include <omx/1.0/WOmxNode.h>
33af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar#include <android/IGraphicBufferSource.h>
3459229481aec5a284d322a2ca80dff836485feb0cYigit Boyar#include <android/IOMXBufferSource.h>
35af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar
36af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyarnamespace android {
3796e1c821dd446d1ed78f8ae61131550588f60a24George Mount
38af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyarenum {
3996e1c821dd446d1ed78f8ae61131550588f60a24George Mount    CONNECT = IBinder::FIRST_CALL_TRANSACTION,
4096e1c821dd446d1ed78f8ae61131550588f60a24George Mount    LIST_NODES,
4196e1c821dd446d1ed78f8ae61131550588f60a24George Mount    ALLOCATE_NODE,
426047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    CREATE_INPUT_SURFACE,
4396e1c821dd446d1ed78f8ae61131550588f60a24George Mount    FREE_NODE,
4496e1c821dd446d1ed78f8ae61131550588f60a24George Mount    SEND_COMMAND,
4596e1c821dd446d1ed78f8ae61131550588f60a24George Mount    GET_PARAMETER,
466047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    SET_PARAMETER,
47af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar    GET_CONFIG,
48af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar    SET_CONFIG,
4996e1c821dd446d1ed78f8ae61131550588f60a24George Mount    SET_PORT_MODE,
50af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar    SET_INPUT_SURFACE,
515bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    PREPARE_FOR_ADAPTIVE_PLAYBACK,
526047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    ALLOC_SECURE_BUFFER,
535bf3700759ff21696becadd4e6fcfe2c0db6cb83Yigit Boyar    USE_BUFFER,
54af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar    FREE_BUFFER,
556047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    FILL_BUFFER,
5643596c2b2997e40b709627419732100d78a62ff0Yigit Boyar    EMPTY_BUFFER,
5796e1c821dd446d1ed78f8ae61131550588f60a24George Mount    GET_EXTENSION_INDEX,
5843596c2b2997e40b709627419732100d78a62ff0Yigit Boyar    OBSERVER_ON_MSG,
5943596c2b2997e40b709627419732100d78a62ff0Yigit Boyar    GET_GRAPHIC_BUFFER_USAGE,
6096e1c821dd446d1ed78f8ae61131550588f60a24George Mount    CONFIGURE_VIDEO_TUNNEL_MODE,
616047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    DISPATCH_MESSAGE,
6296e1c821dd446d1ed78f8ae61131550588f60a24George Mount    SET_QUIRKS,
636047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar};
646047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar
65af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyarclass BpOMX : public BpInterface<IOMX> {
66af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyarpublic:
676047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    explicit BpOMX(const sp<IBinder> &impl)
6859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar        : BpInterface<IOMX>(impl) {
69af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar    }
7096e1c821dd446d1ed78f8ae61131550588f60a24George Mount
7196e1c821dd446d1ed78f8ae61131550588f60a24George Mount    virtual status_t listNodes(List<ComponentInfo> *list) {
726047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        list->clear();
736047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar
746047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        Parcel data, reply;
756047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
766047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        remote()->transact(LIST_NODES, data, &reply);
7796e1c821dd446d1ed78f8ae61131550588f60a24George Mount
786047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        int32_t n = reply.readInt32();
7996e1c821dd446d1ed78f8ae61131550588f60a24George Mount        for (int32_t i = 0; i < n; ++i) {
8096e1c821dd446d1ed78f8ae61131550588f60a24George Mount            list->push_back(ComponentInfo());
8196e1c821dd446d1ed78f8ae61131550588f60a24George Mount            ComponentInfo &info = *--list->end();
8243596c2b2997e40b709627419732100d78a62ff0Yigit Boyar
836047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            info.mName = reply.readString8();
8496e1c821dd446d1ed78f8ae61131550588f60a24George Mount            int32_t numRoles = reply.readInt32();
8596e1c821dd446d1ed78f8ae61131550588f60a24George Mount            for (int32_t j = 0; j < numRoles; ++j) {
866047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                info.mRoles.push_back(reply.readString8());
876047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            }
886047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        }
894df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar
904df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        return OK;
916047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    }
926047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar
93af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar    virtual status_t allocateNode(
946047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            const char *name, const sp<IOMXObserver> &observer,
954df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar            sp<IOMXNode> *omxNode) {
966047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        Parcel data, reply;
976047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
984df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        data.writeCString(name);
994df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        data.writeStrongBinder(IInterface::asBinder(observer));
1006047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        remote()->transact(ALLOCATE_NODE, data, &reply);
1014df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar
1024df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        status_t err = reply.readInt32();
1034df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        if (err == OK) {
104ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount            *omxNode = IOMXNode::asInterface(reply.readStrongBinder());
1056047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        } else {
106ed6428586a939e00d9e66314d5cf1056ad48767eGeorge Mount            omxNode->clear();
1074df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        }
1086047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar
1096047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        return err;
1106047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    }
1116047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar
1126047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar    virtual status_t createInputSurface(
1136047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            sp<IGraphicBufferProducer> *bufferProducer,
1144df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar            sp<IGraphicBufferSource> *bufferSource) {
1156047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        Parcel data, reply;
1166047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        status_t err;
1174df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
1184df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
1194df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar        if (err != OK) {
1204df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar            ALOGW("binder transaction failed: %d", err);
1214df4ba38a62b791bbbc25e923efe8d9c2f9a52e9Yigit Boyar            return err;
1226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        }
12396e1c821dd446d1ed78f8ae61131550588f60a24George Mount
12496e1c821dd446d1ed78f8ae61131550588f60a24George Mount        err = reply.readInt32();
12543596c2b2997e40b709627419732100d78a62ff0Yigit Boyar        if (err != OK) {
126            return err;
127        }
128
129        *bufferProducer = IGraphicBufferProducer::asInterface(
130                reply.readStrongBinder());
131        *bufferSource = IGraphicBufferSource::asInterface(
132                reply.readStrongBinder());
133
134        return err;
135    }
136};
137
138class BpOMXNode : public BpInterface<IOMXNode> {
139public:
140    explicit BpOMXNode(const sp<IBinder> &impl)
141        : BpInterface<IOMXNode>(impl) {
142    }
143
144    virtual status_t freeNode() {
145        Parcel data, reply;
146        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
147        remote()->transact(FREE_NODE, data, &reply);
148
149        return reply.readInt32();
150    }
151
152    virtual status_t sendCommand(
153            OMX_COMMANDTYPE cmd, OMX_S32 param) {
154        Parcel data, reply;
155        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
156        data.writeInt32(cmd);
157        data.writeInt32(param);
158        remote()->transact(SEND_COMMAND, data, &reply);
159
160        return reply.readInt32();
161    }
162
163    virtual status_t getParameter(
164            OMX_INDEXTYPE index,
165            void *params, size_t size) {
166        Parcel data, reply;
167        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
168        data.writeInt32(index);
169        data.writeInt64(size);
170        data.write(params, size);
171        remote()->transact(GET_PARAMETER, data, &reply);
172
173        status_t err = reply.readInt32();
174        if (err != OK) {
175            return err;
176        }
177
178        reply.read(params, size);
179
180        return OK;
181    }
182
183    virtual status_t setParameter(
184            OMX_INDEXTYPE index,
185            const void *params, size_t size) {
186        Parcel data, reply;
187        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
188        data.writeInt32(index);
189        data.writeInt64(size);
190        data.write(params, size);
191        remote()->transact(SET_PARAMETER, data, &reply);
192
193        return reply.readInt32();
194    }
195
196    virtual status_t getConfig(
197            OMX_INDEXTYPE index,
198            void *params, size_t size) {
199        Parcel data, reply;
200        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
201        data.writeInt32(index);
202        data.writeInt64(size);
203        data.write(params, size);
204        remote()->transact(GET_CONFIG, data, &reply);
205
206        status_t err = reply.readInt32();
207        if (err != OK) {
208            return err;
209        }
210
211        reply.read(params, size);
212
213        return OK;
214    }
215
216    virtual status_t setConfig(
217            OMX_INDEXTYPE index,
218            const void *params, size_t size) {
219        Parcel data, reply;
220        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
221        data.writeInt32(index);
222        data.writeInt64(size);
223        data.write(params, size);
224        remote()->transact(SET_CONFIG, data, &reply);
225
226        return reply.readInt32();
227    }
228
229    virtual status_t setPortMode(
230            OMX_U32 port_index, IOMX::PortMode mode) {
231        Parcel data, reply;
232        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
233        data.writeInt32(port_index);
234        data.writeInt32(mode);
235        remote()->transact(SET_PORT_MODE, data, &reply);
236
237        return reply.readInt32();
238    }
239
240    virtual status_t getGraphicBufferUsage(
241            OMX_U32 port_index, OMX_U32* usage) {
242        Parcel data, reply;
243        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
244        data.writeInt32(port_index);
245        remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
246
247        status_t err = reply.readInt32();
248        *usage = reply.readInt32();
249        return err;
250    }
251
252    virtual status_t useBuffer(
253            OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
254        Parcel data, reply;
255        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
256        data.writeInt32(port_index);
257
258        status_t err = omxBuf.writeToParcel(&data);
259        if (err != OK) {
260            return err;
261        }
262
263        remote()->transact(USE_BUFFER, data, &reply);
264
265        err = reply.readInt32();
266        if (err != OK) {
267            *buffer = 0;
268
269            return err;
270        }
271
272        *buffer = (buffer_id)reply.readInt32();
273
274        return err;
275    }
276
277    virtual status_t setInputSurface(
278            const sp<IOMXBufferSource> &bufferSource) {
279        Parcel data, reply;
280        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
281
282        data.writeStrongBinder(IInterface::asBinder(bufferSource));
283
284        status_t err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
285
286        if (err != OK) {
287            ALOGW("binder transaction failed: %d", err);
288            return err;
289        }
290
291        err = reply.readInt32();
292
293        return err;
294    }
295
296    virtual status_t prepareForAdaptivePlayback(
297            OMX_U32 port_index, OMX_BOOL enable,
298            OMX_U32 max_width, OMX_U32 max_height) {
299        Parcel data, reply;
300        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
301        data.writeInt32(port_index);
302        data.writeInt32((int32_t)enable);
303        data.writeInt32(max_width);
304        data.writeInt32(max_height);
305        remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
306
307        status_t err = reply.readInt32();
308        return err;
309    }
310
311    virtual status_t configureVideoTunnelMode(
312            OMX_U32 portIndex, OMX_BOOL tunneled,
313            OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
314        Parcel data, reply;
315        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
316        data.writeInt32(portIndex);
317        data.writeInt32((int32_t)tunneled);
318        data.writeInt32(audioHwSync);
319        remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
320
321        status_t err = reply.readInt32();
322        if (err == OK && sidebandHandle) {
323            *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
324        }
325        return err;
326    }
327
328
329    virtual status_t allocateSecureBuffer(
330            OMX_U32 port_index, size_t size,
331            buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) {
332        Parcel data, reply;
333        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
334        data.writeInt32(port_index);
335        data.writeInt64(size);
336        remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
337
338        status_t err = reply.readInt32();
339        if (err != OK) {
340            *buffer = 0;
341            *buffer_data = NULL;
342            *native_handle = NULL;
343            return err;
344        }
345
346        *buffer = (buffer_id)reply.readInt32();
347        *buffer_data = (void *)reply.readInt64();
348        if (*buffer_data == NULL) {
349            *native_handle = NativeHandle::create(
350                    reply.readNativeHandle(), true /* ownsHandle */);
351        } else {
352            *native_handle = NULL;
353        }
354        return err;
355    }
356
357    virtual status_t freeBuffer(
358            OMX_U32 port_index, buffer_id buffer) {
359        Parcel data, reply;
360        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
361        data.writeInt32(port_index);
362        data.writeInt32((int32_t)buffer);
363        remote()->transact(FREE_BUFFER, data, &reply);
364
365        return reply.readInt32();
366    }
367
368    virtual status_t fillBuffer(
369            buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
370        Parcel data, reply;
371        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
372        data.writeInt32((int32_t)buffer);
373        status_t err = omxBuf.writeToParcel(&data);
374        if (err != OK) {
375            return err;
376        }
377        data.writeInt32(fenceFd >= 0);
378        if (fenceFd >= 0) {
379            data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
380        }
381        remote()->transact(FILL_BUFFER, data, &reply);
382
383        return reply.readInt32();
384    }
385
386    virtual status_t emptyBuffer(
387            buffer_id buffer, const OMXBuffer &omxBuf,
388            OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
389        Parcel data, reply;
390        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
391        data.writeInt32((int32_t)buffer);
392        status_t err = omxBuf.writeToParcel(&data);
393        if (err != OK) {
394            return err;
395        }
396        data.writeInt32(flags);
397        data.writeInt64(timestamp);
398        data.writeInt32(fenceFd >= 0);
399        if (fenceFd >= 0) {
400            data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
401        }
402        remote()->transact(EMPTY_BUFFER, data, &reply);
403
404        return reply.readInt32();
405    }
406
407    virtual status_t getExtensionIndex(
408            const char *parameter_name,
409            OMX_INDEXTYPE *index) {
410        Parcel data, reply;
411        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
412        data.writeCString(parameter_name);
413
414        remote()->transact(GET_EXTENSION_INDEX, data, &reply);
415
416        status_t err = reply.readInt32();
417        if (err == OK) {
418            *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
419        } else {
420            *index = OMX_IndexComponentStartUnused;
421        }
422
423        return err;
424    }
425
426    virtual status_t dispatchMessage(const omx_message &msg) {
427        Parcel data, reply;
428        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
429        data.writeInt32(msg.fenceFd >= 0);
430        if (msg.fenceFd >= 0) {
431            data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
432        }
433        data.writeInt32(msg.type);
434        data.write(&msg.u, sizeof(msg.u));
435
436        remote()->transact(DISPATCH_MESSAGE, data, &reply);
437
438        return reply.readInt32();
439    }
440
441    virtual status_t setQuirks(OMX_U32 quirks) {
442        Parcel data, reply;
443        data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
444        data.writeInt32(quirks);
445
446        remote()->transact(SET_QUIRKS, data, &reply);
447
448        return reply.readInt32();
449    }
450};
451
452using ::android::hardware::media::omx::V1_0::utils::LWOmxNode;
453class HpOMXNode : public HpInterface<BpOMXNode, LWOmxNode> {
454public:
455    HpOMXNode(const sp<IBinder>& base) : PBase(base) {}
456
457    virtual status_t freeNode() {
458        return mBase->freeNode();
459    }
460
461    virtual status_t sendCommand(
462            OMX_COMMANDTYPE cmd, OMX_S32 param) {
463        return mBase->sendCommand(cmd, param);
464    }
465
466    virtual status_t getParameter(
467            OMX_INDEXTYPE index, void *params, size_t size) {
468        return mBase->getParameter(index, params, size);
469    }
470
471    virtual status_t setParameter(
472            OMX_INDEXTYPE index, const void *params, size_t size) {
473        return mBase->setParameter(index, params, size);
474    }
475
476    virtual status_t getConfig(
477            OMX_INDEXTYPE index, void *params, size_t size) {
478        return mBase->getConfig(index, params, size);
479    }
480
481    virtual status_t setConfig(
482            OMX_INDEXTYPE index, const void *params, size_t size) {
483        return mBase->setConfig(index, params, size);
484    }
485
486    virtual status_t setPortMode(
487            OMX_U32 port_index, IOMX::PortMode mode) {
488        return mBase->setPortMode(port_index, mode);
489    }
490
491    virtual status_t prepareForAdaptivePlayback(
492            OMX_U32 portIndex, OMX_BOOL enable,
493            OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight) {
494        return mBase->prepareForAdaptivePlayback(
495                portIndex, enable, maxFrameWidth, maxFrameHeight);
496    }
497
498    virtual status_t configureVideoTunnelMode(
499            OMX_U32 portIndex, OMX_BOOL tunneled,
500            OMX_U32 audioHwSync, native_handle_t **sidebandHandle) {
501        return mBase->configureVideoTunnelMode(
502                portIndex, tunneled, audioHwSync, sidebandHandle);
503    }
504
505    virtual status_t getGraphicBufferUsage(
506            OMX_U32 port_index, OMX_U32* usage) {
507        return mBase->getGraphicBufferUsage(port_index, usage);
508    }
509
510    virtual status_t setInputSurface(
511            const sp<IOMXBufferSource> &bufferSource) {
512        return mBase->setInputSurface(bufferSource);
513    }
514
515    virtual status_t allocateSecureBuffer(
516            OMX_U32 port_index, size_t size, buffer_id *buffer,
517            void **buffer_data, sp<NativeHandle> *native_handle) {
518        return mBase->allocateSecureBuffer(
519                port_index, size, buffer, buffer_data, native_handle);
520    }
521
522    virtual status_t useBuffer(
523            OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
524        return mBase->useBuffer(port_index, omxBuf, buffer);
525    }
526
527    virtual status_t freeBuffer(
528            OMX_U32 port_index, buffer_id buffer) {
529        return mBase->freeBuffer(port_index, buffer);
530    }
531
532    virtual status_t fillBuffer(
533            buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) {
534        return mBase->fillBuffer(buffer, omxBuf, fenceFd);
535    }
536
537    virtual status_t emptyBuffer(
538            buffer_id buffer, const OMXBuffer &omxBuf,
539            OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) {
540        return mBase->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd);
541    }
542
543    virtual status_t getExtensionIndex(
544            const char *parameter_name,
545            OMX_INDEXTYPE *index) {
546        return mBase->getExtensionIndex(parameter_name, index);
547    }
548
549    virtual status_t dispatchMessage(const omx_message &msg) {
550        return mBase->dispatchMessage(msg);
551    }
552
553    // TODO: this is temporary, will be removed when quirks move to OMX side
554    virtual status_t setQuirks(OMX_U32 quirks) {
555        return mBase->setQuirks(quirks);
556    }
557};
558
559IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
560IMPLEMENT_HYBRID_META_INTERFACE(OMXNode, IOmxNode, "android.hardware.IOMXNode");
561
562////////////////////////////////////////////////////////////////////////////////
563
564#define CHECK_OMX_INTERFACE(interface, data, reply) \
565        do { if (!(data).enforceInterface(interface::getInterfaceDescriptor())) { \
566            ALOGW("Call incorrectly routed to " #interface); \
567            return PERMISSION_DENIED; \
568        } } while (0)
569
570status_t BnOMX::onTransact(
571    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
572    switch (code) {
573        case LIST_NODES:
574        {
575            CHECK_OMX_INTERFACE(IOMX, data, reply);
576
577            List<ComponentInfo> list;
578            listNodes(&list);
579
580            reply->writeInt32(list.size());
581            for (List<ComponentInfo>::iterator it = list.begin();
582                 it != list.end(); ++it) {
583                ComponentInfo &cur = *it;
584
585                reply->writeString8(cur.mName);
586                reply->writeInt32(cur.mRoles.size());
587                for (List<String8>::iterator role_it = cur.mRoles.begin();
588                     role_it != cur.mRoles.end(); ++role_it) {
589                    reply->writeString8(*role_it);
590                }
591            }
592
593            return NO_ERROR;
594        }
595
596        case ALLOCATE_NODE:
597        {
598            CHECK_OMX_INTERFACE(IOMX, data, reply);
599
600            const char *name = data.readCString();
601
602            sp<IOMXObserver> observer =
603                interface_cast<IOMXObserver>(data.readStrongBinder());
604
605            if (name == NULL || observer == NULL) {
606                ALOGE("b/26392700");
607                reply->writeInt32(INVALID_OPERATION);
608                return NO_ERROR;
609            }
610
611            sp<IOMXNode> omxNode;
612
613            status_t err = allocateNode(name, observer, &omxNode);
614
615            reply->writeInt32(err);
616            if (err == OK) {
617                reply->writeStrongBinder(IInterface::asBinder(omxNode));
618            }
619
620            return NO_ERROR;
621        }
622
623        case CREATE_INPUT_SURFACE:
624        {
625            CHECK_OMX_INTERFACE(IOMX, data, reply);
626
627            sp<IGraphicBufferProducer> bufferProducer;
628            sp<IGraphicBufferSource> bufferSource;
629            status_t err = createInputSurface(&bufferProducer, &bufferSource);
630
631            reply->writeInt32(err);
632
633            if (err == OK) {
634                reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
635                reply->writeStrongBinder(IInterface::asBinder(bufferSource));
636            }
637
638            return NO_ERROR;
639        }
640
641        default:
642            return BBinder::onTransact(code, data, reply, flags);
643    }
644}
645
646status_t BnOMXNode::onTransact(
647    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
648    switch (code) {
649        case FREE_NODE:
650        {
651            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
652
653            reply->writeInt32(freeNode());
654
655            return NO_ERROR;
656        }
657
658        case SEND_COMMAND:
659        {
660            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
661
662            OMX_COMMANDTYPE cmd =
663                static_cast<OMX_COMMANDTYPE>(data.readInt32());
664
665            OMX_S32 param = data.readInt32();
666            reply->writeInt32(sendCommand(cmd, param));
667
668            return NO_ERROR;
669        }
670
671        case GET_PARAMETER:
672        case SET_PARAMETER:
673        case GET_CONFIG:
674        case SET_CONFIG:
675        {
676            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
677
678            OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
679
680            size_t size = data.readInt64();
681
682            status_t err = NOT_ENOUGH_DATA;
683            void *params = NULL;
684            size_t pageSize = 0;
685            size_t allocSize = 0;
686            bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits);
687            if ((isUsageBits && size < 4) || (!isUsageBits && size < 8)) {
688                // we expect the structure to contain at least the size and
689                // version, 8 bytes total
690                ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code));
691                android_errorWriteLog(0x534e4554, "27207275");
692            } else {
693                err = NO_MEMORY;
694                pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
695                if (size > SIZE_MAX - (pageSize * 2)) {
696                    ALOGE("requested param size too big");
697                } else {
698                    allocSize = (size + pageSize * 2) & ~(pageSize - 1);
699                    params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
700                            MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
701                }
702                if (params != MAP_FAILED && params != NULL) {
703                    err = data.read(params, size);
704                    if (err != OK) {
705                        android_errorWriteLog(0x534e4554, "26914474");
706                    } else {
707                        err = NOT_ENOUGH_DATA;
708                        OMX_U32 declaredSize = *(OMX_U32*)params;
709                        if (index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits &&
710                                declaredSize > size) {
711                            // the buffer says it's bigger than it actually is
712                            ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
713                            android_errorWriteLog(0x534e4554, "27207275");
714                        } else {
715                            // mark the last page as inaccessible, to avoid exploitation
716                            // of codecs that access past the end of the allocation because
717                            // they didn't check the size
718                            if (mprotect((char*)params + allocSize - pageSize, pageSize,
719                                    PROT_NONE) != 0) {
720                                ALOGE("mprotect failed: %s", strerror(errno));
721                            } else {
722                                switch (code) {
723                                    case GET_PARAMETER:
724                                        err = getParameter(index, params, size);
725                                        break;
726                                    case SET_PARAMETER:
727                                        err = setParameter(index, params, size);
728                                        break;
729                                    case GET_CONFIG:
730                                        err = getConfig(index, params, size);
731                                        break;
732                                    case SET_CONFIG:
733                                        err = setConfig(index, params, size);
734                                        break;
735                                    default:
736                                        TRESPASS();
737                                }
738                            }
739                        }
740                    }
741                } else {
742                    ALOGE("couldn't map: %s", strerror(errno));
743                }
744            }
745
746            reply->writeInt32(err);
747
748            if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
749                reply->write(params, size);
750            }
751
752            if (params) {
753                munmap(params, allocSize);
754            }
755            params = NULL;
756
757            return NO_ERROR;
758        }
759
760        case SET_PORT_MODE:
761        {
762            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
763            OMX_U32 port_index = data.readInt32();
764            IOMX::PortMode mode = (IOMX::PortMode) data.readInt32();
765            reply->writeInt32(setPortMode(port_index, mode));
766
767            return NO_ERROR;
768        }
769
770        case GET_GRAPHIC_BUFFER_USAGE:
771        {
772            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
773
774            OMX_U32 port_index = data.readInt32();
775
776            OMX_U32 usage = 0;
777            status_t err = getGraphicBufferUsage(port_index, &usage);
778            reply->writeInt32(err);
779            reply->writeInt32(usage);
780
781            return NO_ERROR;
782        }
783
784        case USE_BUFFER:
785        {
786            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
787
788            OMX_U32 port_index = data.readInt32();
789
790            OMXBuffer omxBuf;
791            status_t err = omxBuf.readFromParcel(&data);
792            if (err != OK) {
793                return err;
794            }
795
796            buffer_id buffer;
797            err = useBuffer(port_index, omxBuf, &buffer);
798            reply->writeInt32(err);
799
800            if (err == OK) {
801                reply->writeInt32((int32_t)buffer);
802            }
803
804            return NO_ERROR;
805        }
806
807        case SET_INPUT_SURFACE:
808        {
809            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
810
811            sp<IOMXBufferSource> bufferSource =
812                    interface_cast<IOMXBufferSource>(data.readStrongBinder());
813
814            status_t err = setInputSurface(bufferSource);
815            reply->writeInt32(err);
816
817            return NO_ERROR;
818        }
819
820        case PREPARE_FOR_ADAPTIVE_PLAYBACK:
821        {
822            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
823
824            OMX_U32 port_index = data.readInt32();
825            OMX_BOOL enable = (OMX_BOOL)data.readInt32();
826            OMX_U32 max_width = data.readInt32();
827            OMX_U32 max_height = data.readInt32();
828
829            status_t err = prepareForAdaptivePlayback(
830                    port_index, enable, max_width, max_height);
831            reply->writeInt32(err);
832
833            return NO_ERROR;
834        }
835
836        case CONFIGURE_VIDEO_TUNNEL_MODE:
837        {
838            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
839
840            OMX_U32 port_index = data.readInt32();
841            OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
842            OMX_U32 audio_hw_sync = data.readInt32();
843
844            native_handle_t *sideband_handle = NULL;
845            status_t err = configureVideoTunnelMode(
846                    port_index, tunneled, audio_hw_sync, &sideband_handle);
847            reply->writeInt32(err);
848            if(err == OK){
849                reply->writeNativeHandle(sideband_handle);
850            }
851
852            return NO_ERROR;
853        }
854
855        case ALLOC_SECURE_BUFFER:
856        {
857            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
858
859            OMX_U32 port_index = data.readInt32();
860            if (!isSecure() || port_index != 0 /* kPortIndexInput */) {
861                ALOGE("b/24310423");
862                reply->writeInt32(INVALID_OPERATION);
863                return NO_ERROR;
864            }
865
866            size_t size = data.readInt64();
867
868            buffer_id buffer;
869            void *buffer_data = NULL;
870            sp<NativeHandle> native_handle;
871            status_t err = allocateSecureBuffer(
872                    port_index, size, &buffer, &buffer_data, &native_handle);
873            reply->writeInt32(err);
874
875            if (err == OK) {
876                reply->writeInt32((int32_t)buffer);
877                reply->writeInt64((uintptr_t)buffer_data);
878                if (buffer_data == NULL) {
879                    reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle());
880                }
881            }
882
883            return NO_ERROR;
884        }
885
886        case FREE_BUFFER:
887        {
888            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
889
890            OMX_U32 port_index = data.readInt32();
891            buffer_id buffer = (buffer_id)data.readInt32();
892            reply->writeInt32(freeBuffer(port_index, buffer));
893
894            return NO_ERROR;
895        }
896
897        case FILL_BUFFER:
898        {
899            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
900
901            buffer_id buffer = (buffer_id)data.readInt32();
902
903            OMXBuffer omxBuf;
904            status_t err = omxBuf.readFromParcel(&data);
905            if (err != OK) {
906                return err;
907            }
908
909            bool haveFence = data.readInt32();
910            int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
911
912            reply->writeInt32(fillBuffer(buffer, omxBuf, fenceFd));
913
914            return NO_ERROR;
915        }
916
917        case EMPTY_BUFFER:
918        {
919            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
920
921            buffer_id buffer = (buffer_id)data.readInt32();
922            OMXBuffer omxBuf;
923            status_t err = omxBuf.readFromParcel(&data);
924            if (err != OK) {
925                return err;
926            }
927            OMX_U32 flags = data.readInt32();
928            OMX_TICKS timestamp = data.readInt64();
929            bool haveFence = data.readInt32();
930            int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
931            reply->writeInt32(emptyBuffer(
932                    buffer, omxBuf, flags, timestamp, fenceFd));
933
934            return NO_ERROR;
935        }
936
937        case GET_EXTENSION_INDEX:
938        {
939            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
940
941            const char *parameter_name = data.readCString();
942
943            if (parameter_name == NULL) {
944                ALOGE("b/26392700");
945                reply->writeInt32(INVALID_OPERATION);
946                return NO_ERROR;
947            }
948
949            OMX_INDEXTYPE index;
950            status_t err = getExtensionIndex(parameter_name, &index);
951
952            reply->writeInt32(err);
953
954            if (err == OK) {
955                reply->writeInt32(index);
956            }
957
958            return OK;
959        }
960
961        case DISPATCH_MESSAGE:
962        {
963            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
964            omx_message msg;
965            int haveFence = data.readInt32();
966            msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
967            msg.type = (typeof(msg.type))data.readInt32();
968            status_t err = data.read(&msg.u, sizeof(msg.u));
969
970            if (err == OK) {
971                err = dispatchMessage(msg);
972            }
973            reply->writeInt32(err);
974
975            return NO_ERROR;
976        }
977
978        case SET_QUIRKS:
979        {
980            CHECK_OMX_INTERFACE(IOMXNode, data, reply);
981
982            OMX_U32 quirks = data.readInt32();
983
984            reply->writeInt32(setQuirks(quirks));
985
986            return NO_ERROR;
987        }
988
989        default:
990            return BBinder::onTransact(code, data, reply, flags);
991    }
992}
993
994////////////////////////////////////////////////////////////////////////////////
995
996class BpOMXObserver : public BpInterface<IOMXObserver> {
997public:
998    explicit BpOMXObserver(const sp<IBinder> &impl)
999        : BpInterface<IOMXObserver>(impl) {
1000    }
1001
1002    virtual void onMessages(const std::list<omx_message> &messages) {
1003        Parcel data, reply;
1004        std::list<omx_message>::const_iterator it = messages.cbegin();
1005        if (messages.empty()) {
1006            return;
1007        }
1008        data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
1009        while (it != messages.cend()) {
1010            const omx_message &msg = *it++;
1011            data.writeInt32(msg.fenceFd >= 0);
1012            if (msg.fenceFd >= 0) {
1013                data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
1014            }
1015            data.writeInt32(msg.type);
1016            data.write(&msg.u, sizeof(msg.u));
1017            ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
1018        }
1019        data.writeInt32(-1); // mark end
1020        remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
1021    }
1022};
1023
1024IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
1025
1026status_t BnOMXObserver::onTransact(
1027    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
1028    switch (code) {
1029        case OBSERVER_ON_MSG:
1030        {
1031            CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
1032            std::list<omx_message> messages;
1033            status_t err = FAILED_TRANSACTION; // must receive at least one message
1034            do {
1035                int haveFence = data.readInt32();
1036                if (haveFence < 0) { // we use -1 to mark end of messages
1037                    break;
1038                }
1039                omx_message msg;
1040                msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1041                msg.type = (typeof(msg.type))data.readInt32();
1042                err = data.read(&msg.u, sizeof(msg.u));
1043                ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
1044                messages.push_back(msg);
1045            } while (err == OK);
1046
1047            if (err == OK) {
1048                onMessages(messages);
1049            }
1050
1051            return err;
1052        }
1053
1054        default:
1055            return BBinder::onTransact(code, data, reply, flags);
1056    }
1057}
1058
1059}  // namespace android
1060