blob: 9b3ef30c0f14efc4a988c450023c3391f171033e [file] [log] [blame]
James Dong27c17442011-03-17 11:02:04 -07001/*
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
Andreas Huber20111aa2009-07-14 16:56:47 -070017//#define LOG_NDEBUG 0
18#define LOG_TAG "IOMX"
19#include <utils/Log.h>
20
Marco Nelissen2720c8b2016-02-29 12:47:20 -080021#include <sys/mman.h>
22
Andreas Huber20111aa2009-07-14 16:56:47 -070023#include <binder/IMemory.h>
24#include <binder/Parcel.h>
25#include <media/IOMX.h>
Andreas Huberb3912902011-01-19 10:34:52 -080026#include <media/stagefright/foundation/ADebug.h>
Marco Nelissenc1c50e72016-03-10 15:02:13 -080027#include <media/openmax/OMX_IndexExt.h>
Lajos Molnar7e0bef82016-05-09 10:48:30 -070028#include <utils/NativeHandle.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070029
30namespace android {
31
32enum {
33 CONNECT = IBinder::FIRST_CALL_TRANSACTION,
Andreas Huber7eaa9c92010-01-15 15:28:19 -080034 LIVES_LOCALLY,
Andreas Huber20111aa2009-07-14 16:56:47 -070035 LIST_NODES,
36 ALLOCATE_NODE,
37 FREE_NODE,
38 SEND_COMMAND,
39 GET_PARAMETER,
40 SET_PARAMETER,
Andreas Huber693d2712009-08-14 14:37:10 -070041 GET_CONFIG,
42 SET_CONFIG,
Jamie Gennisb1d666f2011-10-19 21:14:13 -070043 GET_STATE,
Lajos Molnara63141a2016-02-11 16:40:36 -080044 ENABLE_NATIVE_BUFFERS,
Andreas Huber20111aa2009-07-14 16:56:47 -070045 USE_BUFFER,
Jamie Gennis83750ea2010-08-30 16:48:38 -070046 USE_GRAPHIC_BUFFER,
Andy McFadden7cd58532013-02-19 07:28:30 -080047 CREATE_INPUT_SURFACE,
Chong Zhangd291c222015-04-30 18:15:52 -070048 CREATE_PERSISTENT_INPUT_SURFACE,
Chong Zhang8f469e12015-05-13 10:21:33 -070049 SET_INPUT_SURFACE,
Andy McFadden7cd58532013-02-19 07:28:30 -080050 SIGNAL_END_OF_INPUT_STREAM,
James Donge8707722010-10-20 17:38:41 -070051 STORE_META_DATA_IN_BUFFERS,
Lajos Molnar56ce7262013-05-02 16:30:48 -070052 PREPARE_FOR_ADAPTIVE_PLAYBACK,
Lajos Molnara63141a2016-02-11 16:40:36 -080053 ALLOC_SECURE_BUFFER,
Andreas Huber20111aa2009-07-14 16:56:47 -070054 ALLOC_BUFFER_WITH_BACKUP,
55 FREE_BUFFER,
Andreas Huber20111aa2009-07-14 16:56:47 -070056 FILL_BUFFER,
57 EMPTY_BUFFER,
Andreas Huber693d2712009-08-14 14:37:10 -070058 GET_EXTENSION_INDEX,
Andreas Huber20111aa2009-07-14 16:56:47 -070059 OBSERVER_ON_MSG,
Jamie Gennise2ce6452011-02-23 19:01:28 -080060 GET_GRAPHIC_BUFFER_USAGE,
Andreas Hubere40cda72013-07-17 13:55:26 -070061 SET_INTERNAL_OPTION,
Lajos Molnard0715862013-07-22 12:57:43 -070062 UPDATE_GRAPHIC_BUFFER_IN_META,
Rachad5a446aa2014-07-29 16:47:56 -070063 CONFIGURE_VIDEO_TUNNEL_MODE,
Lajos Molnar7e0bef82016-05-09 10:48:30 -070064 UPDATE_NATIVE_HANDLE_IN_META,
Andreas Huber20111aa2009-07-14 16:56:47 -070065};
66
Andreas Huber20111aa2009-07-14 16:56:47 -070067class BpOMX : public BpInterface<IOMX> {
68public:
69 BpOMX(const sp<IBinder> &impl)
70 : BpInterface<IOMX>(impl) {
71 }
72
Andreas Huberd459b482012-01-31 11:16:24 -080073 virtual bool livesLocally(node_id node, pid_t pid) {
Andreas Huber7eaa9c92010-01-15 15:28:19 -080074 Parcel data, reply;
75 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -070076 data.writeInt32((int32_t)node);
Andreas Huber7eaa9c92010-01-15 15:28:19 -080077 data.writeInt32(pid);
78 remote()->transact(LIVES_LOCALLY, data, &reply);
79
80 return reply.readInt32() != 0;
81 }
82
Andreas Huber134ee6a2009-12-16 09:30:55 -080083 virtual status_t listNodes(List<ComponentInfo> *list) {
Andreas Huber20111aa2009-07-14 16:56:47 -070084 list->clear();
85
86 Parcel data, reply;
87 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
88 remote()->transact(LIST_NODES, data, &reply);
89
90 int32_t n = reply.readInt32();
91 for (int32_t i = 0; i < n; ++i) {
Andreas Huber134ee6a2009-12-16 09:30:55 -080092 list->push_back(ComponentInfo());
93 ComponentInfo &info = *--list->end();
Andreas Huber20111aa2009-07-14 16:56:47 -070094
Andreas Huber134ee6a2009-12-16 09:30:55 -080095 info.mName = reply.readString8();
96 int32_t numRoles = reply.readInt32();
97 for (int32_t j = 0; j < numRoles; ++j) {
98 info.mRoles.push_back(reply.readString8());
99 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700100 }
101
102 return OK;
103 }
104
Andreas Huber318ad9c2009-10-15 13:46:54 -0700105 virtual status_t allocateNode(
Marco Nelissen23858872016-02-17 13:12:13 -0800106 const char *name, const sp<IOMXObserver> &observer,
107 sp<IBinder> *nodeBinder,
108 node_id *node) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700109 Parcel data, reply;
110 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
111 data.writeCString(name);
Marco Nelissen06b46062014-11-14 07:58:25 -0800112 data.writeStrongBinder(IInterface::asBinder(observer));
Andreas Huber20111aa2009-07-14 16:56:47 -0700113 remote()->transact(ALLOCATE_NODE, data, &reply);
114
115 status_t err = reply.readInt32();
116 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700117 *node = (node_id)reply.readInt32();
Marco Nelissen23858872016-02-17 13:12:13 -0800118 if (nodeBinder != NULL) {
119 *nodeBinder = remote();
120 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700121 } else {
122 *node = 0;
123 }
124
125 return err;
126 }
127
Andreas Huber318ad9c2009-10-15 13:46:54 -0700128 virtual status_t freeNode(node_id node) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700129 Parcel data, reply;
130 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700131 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700132 remote()->transact(FREE_NODE, data, &reply);
133
134 return reply.readInt32();
135 }
136
Andreas Huber318ad9c2009-10-15 13:46:54 -0700137 virtual status_t sendCommand(
Andreas Huber20111aa2009-07-14 16:56:47 -0700138 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
139 Parcel data, reply;
140 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700141 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700142 data.writeInt32(cmd);
143 data.writeInt32(param);
144 remote()->transact(SEND_COMMAND, data, &reply);
145
146 return reply.readInt32();
147 }
148
Andreas Huber318ad9c2009-10-15 13:46:54 -0700149 virtual status_t getParameter(
Andreas Huber20111aa2009-07-14 16:56:47 -0700150 node_id node, OMX_INDEXTYPE index,
151 void *params, size_t size) {
152 Parcel data, reply;
153 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700154 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700155 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800156 data.writeInt64(size);
Andreas Huber20111aa2009-07-14 16:56:47 -0700157 data.write(params, size);
158 remote()->transact(GET_PARAMETER, data, &reply);
159
160 status_t err = reply.readInt32();
161 if (err != OK) {
162 return err;
163 }
164
165 reply.read(params, size);
166
167 return OK;
168 }
169
Andreas Huber318ad9c2009-10-15 13:46:54 -0700170 virtual status_t setParameter(
Andreas Huber20111aa2009-07-14 16:56:47 -0700171 node_id node, OMX_INDEXTYPE index,
172 const void *params, size_t size) {
173 Parcel data, reply;
174 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700175 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700176 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800177 data.writeInt64(size);
Andreas Huber20111aa2009-07-14 16:56:47 -0700178 data.write(params, size);
179 remote()->transact(SET_PARAMETER, data, &reply);
180
181 return reply.readInt32();
182 }
183
Andreas Huber318ad9c2009-10-15 13:46:54 -0700184 virtual status_t getConfig(
Andreas Huber693d2712009-08-14 14:37:10 -0700185 node_id node, OMX_INDEXTYPE index,
186 void *params, size_t size) {
187 Parcel data, reply;
188 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700189 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700190 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800191 data.writeInt64(size);
Andreas Huber693d2712009-08-14 14:37:10 -0700192 data.write(params, size);
193 remote()->transact(GET_CONFIG, data, &reply);
194
195 status_t err = reply.readInt32();
196 if (err != OK) {
197 return err;
198 }
199
200 reply.read(params, size);
201
202 return OK;
203 }
204
Andreas Huber318ad9c2009-10-15 13:46:54 -0700205 virtual status_t setConfig(
Andreas Huber693d2712009-08-14 14:37:10 -0700206 node_id node, OMX_INDEXTYPE index,
207 const void *params, size_t size) {
208 Parcel data, reply;
209 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700210 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700211 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800212 data.writeInt64(size);
Andreas Huber693d2712009-08-14 14:37:10 -0700213 data.write(params, size);
214 remote()->transact(SET_CONFIG, data, &reply);
215
216 return reply.readInt32();
217 }
218
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700219 virtual status_t getState(
220 node_id node, OMX_STATETYPE* state) {
221 Parcel data, reply;
222 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700223 data.writeInt32((int32_t)node);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700224 remote()->transact(GET_STATE, data, &reply);
225
226 *state = static_cast<OMX_STATETYPE>(reply.readInt32());
227 return reply.readInt32();
228 }
229
Lajos Molnara63141a2016-02-11 16:40:36 -0800230 virtual status_t enableNativeBuffers(
231 node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
Jamie Gennis83750ea2010-08-30 16:48:38 -0700232 Parcel data, reply;
233 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700234 data.writeInt32((int32_t)node);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700235 data.writeInt32(port_index);
Lajos Molnara63141a2016-02-11 16:40:36 -0800236 data.writeInt32((uint32_t)graphic);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700237 data.writeInt32((uint32_t)enable);
Lajos Molnara63141a2016-02-11 16:40:36 -0800238 remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700239
240 status_t err = reply.readInt32();
241 return err;
242 }
243
Jamie Gennise2ce6452011-02-23 19:01:28 -0800244 virtual status_t getGraphicBufferUsage(
245 node_id node, OMX_U32 port_index, OMX_U32* usage) {
246 Parcel data, reply;
247 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700248 data.writeInt32((int32_t)node);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800249 data.writeInt32(port_index);
250 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
251
252 status_t err = reply.readInt32();
253 *usage = reply.readInt32();
254 return err;
255 }
256
Andreas Huber318ad9c2009-10-15 13:46:54 -0700257 virtual status_t useBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700258 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700259 buffer_id *buffer, OMX_U32 allottedSize) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700260 Parcel data, reply;
261 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700262 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700263 data.writeInt32(port_index);
Marco Nelissen06b46062014-11-14 07:58:25 -0800264 data.writeStrongBinder(IInterface::asBinder(params));
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700265 data.writeInt32(allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700266 remote()->transact(USE_BUFFER, data, &reply);
267
268 status_t err = reply.readInt32();
269 if (err != OK) {
270 *buffer = 0;
271
272 return err;
273 }
274
Andy Hung609b8152014-05-02 11:05:04 -0700275 *buffer = (buffer_id)reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700276
277 return err;
278 }
279
Jamie Gennis83750ea2010-08-30 16:48:38 -0700280
281 virtual status_t useGraphicBuffer(
282 node_id node, OMX_U32 port_index,
283 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
284 Parcel data, reply;
285 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700286 data.writeInt32((int32_t)node);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700287 data.writeInt32(port_index);
288 data.write(*graphicBuffer);
289 remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
290
291 status_t err = reply.readInt32();
292 if (err != OK) {
293 *buffer = 0;
294
295 return err;
296 }
297
Andy Hung609b8152014-05-02 11:05:04 -0700298 *buffer = (buffer_id)reply.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700299
300 return err;
301 }
302
Lajos Molnard0715862013-07-22 12:57:43 -0700303 virtual status_t updateGraphicBufferInMeta(
304 node_id node, OMX_U32 port_index,
305 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
306 Parcel data, reply;
307 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700308 data.writeInt32((int32_t)node);
Lajos Molnard0715862013-07-22 12:57:43 -0700309 data.writeInt32(port_index);
310 data.write(*graphicBuffer);
Andy Hung609b8152014-05-02 11:05:04 -0700311 data.writeInt32((int32_t)buffer);
Lajos Molnard0715862013-07-22 12:57:43 -0700312 remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
313
314 status_t err = reply.readInt32();
315 return err;
316 }
317
Lajos Molnar7e0bef82016-05-09 10:48:30 -0700318 virtual status_t updateNativeHandleInMeta(
319 node_id node, OMX_U32 port_index,
320 const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
321 Parcel data, reply;
322 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
323 data.writeInt32((int32_t)node);
324 data.writeInt32(port_index);
325 data.writeInt32(nativeHandle != NULL);
326 if (nativeHandle != NULL) {
327 data.writeNativeHandle(nativeHandle->handle());
328 }
329 data.writeInt32((int32_t)buffer);
330 remote()->transact(UPDATE_NATIVE_HANDLE_IN_META, data, &reply);
331
332 status_t err = reply.readInt32();
333 return err;
334 }
335
Andy McFadden7cd58532013-02-19 07:28:30 -0800336 virtual status_t createInputSurface(
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800337 node_id node, OMX_U32 port_index, android_dataspace dataSpace,
Lajos Molnar05421982015-05-15 20:39:14 -0700338 sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
Andy McFadden7cd58532013-02-19 07:28:30 -0800339 Parcel data, reply;
340 status_t err;
341 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700342 data.writeInt32((int32_t)node);
Andy McFadden7cd58532013-02-19 07:28:30 -0800343 data.writeInt32(port_index);
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800344 data.writeInt32(dataSpace);
Andy McFadden7cd58532013-02-19 07:28:30 -0800345 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
346 if (err != OK) {
347 ALOGW("binder transaction failed: %d", err);
348 return err;
349 }
350
Lajos Molnar05421982015-05-15 20:39:14 -0700351 // read type even if createInputSurface failed
352 int negotiatedType = reply.readInt32();
353 if (type != NULL) {
354 *type = (MetadataBufferType)negotiatedType;
355 }
356
Andy McFadden7cd58532013-02-19 07:28:30 -0800357 err = reply.readInt32();
358 if (err != OK) {
359 return err;
360 }
361
362 *bufferProducer = IGraphicBufferProducer::asInterface(
363 reply.readStrongBinder());
364
365 return err;
366 }
367
Chong Zhangd291c222015-04-30 18:15:52 -0700368 virtual status_t createPersistentInputSurface(
369 sp<IGraphicBufferProducer> *bufferProducer,
370 sp<IGraphicBufferConsumer> *bufferConsumer) {
371 Parcel data, reply;
372 status_t err;
373 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
374 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply);
375 if (err != OK) {
376 ALOGW("binder transaction failed: %d", err);
377 return err;
378 }
379
380 err = reply.readInt32();
381 if (err != OK) {
382 return err;
383 }
384
385 *bufferProducer = IGraphicBufferProducer::asInterface(
386 reply.readStrongBinder());
387 *bufferConsumer = IGraphicBufferConsumer::asInterface(
388 reply.readStrongBinder());
389
390 return err;
391 }
392
Chong Zhang8f469e12015-05-13 10:21:33 -0700393 virtual status_t setInputSurface(
Chong Zhangd291c222015-04-30 18:15:52 -0700394 node_id node, OMX_U32 port_index,
Lajos Molnar05421982015-05-15 20:39:14 -0700395 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) {
Chong Zhangd291c222015-04-30 18:15:52 -0700396 Parcel data, reply;
397 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
398 status_t err;
399 data.writeInt32((int32_t)node);
400 data.writeInt32(port_index);
401 data.writeStrongBinder(IInterface::asBinder(bufferConsumer));
402
Chong Zhang8f469e12015-05-13 10:21:33 -0700403 err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
Chong Zhangd291c222015-04-30 18:15:52 -0700404
405 if (err != OK) {
406 ALOGW("binder transaction failed: %d", err);
407 return err;
408 }
Lajos Molnar05421982015-05-15 20:39:14 -0700409
410 // read type even if setInputSurface failed
411 int negotiatedType = reply.readInt32();
412 if (type != NULL) {
413 *type = (MetadataBufferType)negotiatedType;
414 }
415
Chong Zhangd291c222015-04-30 18:15:52 -0700416 return reply.readInt32();
417 }
418
Andy McFadden7cd58532013-02-19 07:28:30 -0800419 virtual status_t signalEndOfInputStream(node_id node) {
420 Parcel data, reply;
421 status_t err;
422 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700423 data.writeInt32((int32_t)node);
Andy McFadden7cd58532013-02-19 07:28:30 -0800424 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply);
425 if (err != OK) {
426 ALOGW("binder transaction failed: %d", err);
427 return err;
428 }
429
430 return reply.readInt32();
431 }
432
James Donge8707722010-10-20 17:38:41 -0700433 virtual status_t storeMetaDataInBuffers(
Lajos Molnar05421982015-05-15 20:39:14 -0700434 node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
James Donge8707722010-10-20 17:38:41 -0700435 Parcel data, reply;
436 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700437 data.writeInt32((int32_t)node);
James Donge8707722010-10-20 17:38:41 -0700438 data.writeInt32(port_index);
439 data.writeInt32((uint32_t)enable);
440 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
441
Lajos Molnar05421982015-05-15 20:39:14 -0700442 // read type even storeMetaDataInBuffers failed
443 int negotiatedType = reply.readInt32();
444 if (type != NULL) {
445 *type = (MetadataBufferType)negotiatedType;
446 }
447
448 return reply.readInt32();
James Donge8707722010-10-20 17:38:41 -0700449 }
450
Lajos Molnar56ce7262013-05-02 16:30:48 -0700451 virtual status_t prepareForAdaptivePlayback(
452 node_id node, OMX_U32 port_index, OMX_BOOL enable,
453 OMX_U32 max_width, OMX_U32 max_height) {
454 Parcel data, reply;
455 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700456 data.writeInt32((int32_t)node);
Lajos Molnar56ce7262013-05-02 16:30:48 -0700457 data.writeInt32(port_index);
458 data.writeInt32((int32_t)enable);
459 data.writeInt32(max_width);
460 data.writeInt32(max_height);
461 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
462
463 status_t err = reply.readInt32();
464 return err;
465 }
466
Rachad5a446aa2014-07-29 16:47:56 -0700467 virtual status_t configureVideoTunnelMode(
468 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
469 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
470 Parcel data, reply;
471 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
472 data.writeInt32((int32_t)node);
473 data.writeInt32(portIndex);
474 data.writeInt32((int32_t)tunneled);
475 data.writeInt32(audioHwSync);
476 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
477
478 status_t err = reply.readInt32();
mspector@google.com9d72eb02016-02-08 10:56:13 -0800479 if (err == OK && sidebandHandle) {
Rachad5a446aa2014-07-29 16:47:56 -0700480 *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
481 }
482 return err;
483 }
484
485
Lajos Molnara63141a2016-02-11 16:40:36 -0800486 virtual status_t allocateSecureBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700487 node_id node, OMX_U32 port_index, size_t size,
Lajos Molnara63141a2016-02-11 16:40:36 -0800488 buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700489 Parcel data, reply;
490 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700491 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700492 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800493 data.writeInt64(size);
Lajos Molnara63141a2016-02-11 16:40:36 -0800494 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700495
496 status_t err = reply.readInt32();
497 if (err != OK) {
498 *buffer = 0;
Lajos Molnara63141a2016-02-11 16:40:36 -0800499 *buffer_data = NULL;
500 *native_handle = NULL;
Andreas Huber20111aa2009-07-14 16:56:47 -0700501 return err;
502 }
503
Andy Hung609b8152014-05-02 11:05:04 -0700504 *buffer = (buffer_id)reply.readInt32();
505 *buffer_data = (void *)reply.readInt64();
Lajos Molnara63141a2016-02-11 16:40:36 -0800506 if (*buffer_data == NULL) {
507 *native_handle = reply.readNativeHandle();
508 } else {
509 *native_handle = NULL;
510 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700511 return err;
512 }
513
Andreas Huber318ad9c2009-10-15 13:46:54 -0700514 virtual status_t allocateBufferWithBackup(
Andreas Huber20111aa2009-07-14 16:56:47 -0700515 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700516 buffer_id *buffer, OMX_U32 allottedSize) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700517 Parcel data, reply;
518 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700519 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700520 data.writeInt32(port_index);
Marco Nelissen06b46062014-11-14 07:58:25 -0800521 data.writeStrongBinder(IInterface::asBinder(params));
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700522 data.writeInt32(allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700523 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
524
525 status_t err = reply.readInt32();
526 if (err != OK) {
527 *buffer = 0;
528
529 return err;
530 }
531
Andy Hung609b8152014-05-02 11:05:04 -0700532 *buffer = (buffer_id)reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700533
534 return err;
535 }
536
Andreas Huber318ad9c2009-10-15 13:46:54 -0700537 virtual status_t freeBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700538 node_id node, OMX_U32 port_index, buffer_id buffer) {
539 Parcel data, reply;
540 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700541 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700542 data.writeInt32(port_index);
Andy Hung609b8152014-05-02 11:05:04 -0700543 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700544 remote()->transact(FREE_BUFFER, data, &reply);
545
546 return reply.readInt32();
547 }
548
Lajos Molnar15ab4992015-06-01 10:54:31 -0700549 virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700550 Parcel data, reply;
551 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700552 data.writeInt32((int32_t)node);
553 data.writeInt32((int32_t)buffer);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700554 data.writeInt32(fenceFd >= 0);
555 if (fenceFd >= 0) {
556 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
557 }
Andreas Huber36efa032009-10-08 11:02:27 -0700558 remote()->transact(FILL_BUFFER, data, &reply);
559
560 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700561 }
562
Andreas Huber318ad9c2009-10-15 13:46:54 -0700563 virtual status_t emptyBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700564 node_id node,
565 buffer_id buffer,
566 OMX_U32 range_offset, OMX_U32 range_length,
Lajos Molnar15ab4992015-06-01 10:54:31 -0700567 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700568 Parcel data, reply;
569 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700570 data.writeInt32((int32_t)node);
571 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700572 data.writeInt32(range_offset);
573 data.writeInt32(range_length);
574 data.writeInt32(flags);
575 data.writeInt64(timestamp);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700576 data.writeInt32(fenceFd >= 0);
577 if (fenceFd >= 0) {
578 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
579 }
Andreas Huber36efa032009-10-08 11:02:27 -0700580 remote()->transact(EMPTY_BUFFER, data, &reply);
581
582 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700583 }
Andreas Huber8b938cd2009-07-31 11:52:50 -0700584
Andreas Huber318ad9c2009-10-15 13:46:54 -0700585 virtual status_t getExtensionIndex(
Andreas Huber693d2712009-08-14 14:37:10 -0700586 node_id node,
587 const char *parameter_name,
588 OMX_INDEXTYPE *index) {
589 Parcel data, reply;
590 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700591 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700592 data.writeCString(parameter_name);
593
594 remote()->transact(GET_EXTENSION_INDEX, data, &reply);
595
596 status_t err = reply.readInt32();
597 if (err == OK) {
598 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
599 } else {
600 *index = OMX_IndexComponentStartUnused;
601 }
602
603 return err;
604 }
Andreas Hubere40cda72013-07-17 13:55:26 -0700605
606 virtual status_t setInternalOption(
607 node_id node,
608 OMX_U32 port_index,
609 InternalOptionType type,
610 const void *optionData,
611 size_t size) {
612 Parcel data, reply;
613 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700614 data.writeInt32((int32_t)node);
Andreas Hubere40cda72013-07-17 13:55:26 -0700615 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800616 data.writeInt64(size);
Andreas Hubere40cda72013-07-17 13:55:26 -0700617 data.write(optionData, size);
618 data.writeInt32(type);
619 remote()->transact(SET_INTERNAL_OPTION, data, &reply);
620
621 return reply.readInt32();
622 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700623};
624
625IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
626
627////////////////////////////////////////////////////////////////////////////////
628
Andy McFadden7cd58532013-02-19 07:28:30 -0800629#define CHECK_OMX_INTERFACE(interface, data, reply) \
Andreas Huber20111aa2009-07-14 16:56:47 -0700630 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
Steve Block5ff1dd52012-01-05 23:22:43 +0000631 ALOGW("Call incorrectly routed to " #interface); \
Andreas Huber20111aa2009-07-14 16:56:47 -0700632 return PERMISSION_DENIED; \
633 } } while (0)
634
635status_t BnOMX::onTransact(
636 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
637 switch (code) {
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800638 case LIVES_LOCALLY:
639 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800640 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andy Hung609b8152014-05-02 11:05:04 -0700641 node_id node = (node_id)data.readInt32();
Andreas Huberd459b482012-01-31 11:16:24 -0800642 pid_t pid = (pid_t)data.readInt32();
643 reply->writeInt32(livesLocally(node, pid));
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800644
645 return OK;
646 }
647
Andreas Huber20111aa2009-07-14 16:56:47 -0700648 case LIST_NODES:
649 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800650 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700651
Andreas Huber134ee6a2009-12-16 09:30:55 -0800652 List<ComponentInfo> list;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700653 listNodes(&list);
Andreas Huber20111aa2009-07-14 16:56:47 -0700654
655 reply->writeInt32(list.size());
Andreas Huber134ee6a2009-12-16 09:30:55 -0800656 for (List<ComponentInfo>::iterator it = list.begin();
Andreas Huber20111aa2009-07-14 16:56:47 -0700657 it != list.end(); ++it) {
Andreas Huber134ee6a2009-12-16 09:30:55 -0800658 ComponentInfo &cur = *it;
659
660 reply->writeString8(cur.mName);
661 reply->writeInt32(cur.mRoles.size());
662 for (List<String8>::iterator role_it = cur.mRoles.begin();
663 role_it != cur.mRoles.end(); ++role_it) {
664 reply->writeString8(*role_it);
665 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700666 }
667
668 return NO_ERROR;
669 }
670
671 case ALLOCATE_NODE:
672 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800673 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700674
Andreas Huber318ad9c2009-10-15 13:46:54 -0700675 const char *name = data.readCString();
676
677 sp<IOMXObserver> observer =
678 interface_cast<IOMXObserver>(data.readStrongBinder());
679
Wei Jia56c95c92016-01-06 10:30:46 -0800680 if (name == NULL || observer == NULL) {
681 ALOGE("b/26392700");
682 reply->writeInt32(INVALID_OPERATION);
683 return NO_ERROR;
684 }
685
Andreas Huber20111aa2009-07-14 16:56:47 -0700686 node_id node;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700687
Marco Nelissen23858872016-02-17 13:12:13 -0800688 status_t err = allocateNode(name, observer,
689 NULL /* nodeBinder */, &node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700690 reply->writeInt32(err);
691 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700692 reply->writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700693 }
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800694
Andreas Huber20111aa2009-07-14 16:56:47 -0700695 return NO_ERROR;
696 }
697
698 case FREE_NODE:
699 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800700 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700701
Andy Hung609b8152014-05-02 11:05:04 -0700702 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700703
Andreas Huber318ad9c2009-10-15 13:46:54 -0700704 reply->writeInt32(freeNode(node));
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800705
Andreas Huber20111aa2009-07-14 16:56:47 -0700706 return NO_ERROR;
707 }
708
709 case SEND_COMMAND:
710 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800711 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700712
Andy Hung609b8152014-05-02 11:05:04 -0700713 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700714
715 OMX_COMMANDTYPE cmd =
716 static_cast<OMX_COMMANDTYPE>(data.readInt32());
717
718 OMX_S32 param = data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -0700719 reply->writeInt32(sendCommand(node, cmd, param));
Andreas Huber20111aa2009-07-14 16:56:47 -0700720
721 return NO_ERROR;
722 }
723
724 case GET_PARAMETER:
Andreas Huber20111aa2009-07-14 16:56:47 -0700725 case SET_PARAMETER:
Andreas Huber693d2712009-08-14 14:37:10 -0700726 case GET_CONFIG:
Andreas Huber693d2712009-08-14 14:37:10 -0700727 case SET_CONFIG:
Andreas Hubere40cda72013-07-17 13:55:26 -0700728 case SET_INTERNAL_OPTION:
Andreas Huber693d2712009-08-14 14:37:10 -0700729 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800730 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -0700731
Andy Hung609b8152014-05-02 11:05:04 -0700732 node_id node = (node_id)data.readInt32();
Andreas Huber693d2712009-08-14 14:37:10 -0700733 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
734
Glenn Kastene03dd222014-01-28 11:04:39 -0800735 size_t size = data.readInt64();
Andreas Huber693d2712009-08-14 14:37:10 -0700736
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800737 status_t err = NOT_ENOUGH_DATA;
738 void *params = NULL;
739 size_t pageSize = 0;
740 size_t allocSize = 0;
Marco Nelissen788b0b62016-03-21 11:31:53 -0700741 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits);
742 if ((isUsageBits && size < 4) ||
743 (!isUsageBits && code != SET_INTERNAL_OPTION && size < 8)) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800744 // we expect the structure to contain at least the size and
745 // version, 8 bytes total
Marco Nelissen788b0b62016-03-21 11:31:53 -0700746 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code));
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800747 android_errorWriteLog(0x534e4554, "27207275");
748 } else {
749 err = NO_MEMORY;
750 pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
751 if (size > SIZE_MAX - (pageSize * 2)) {
752 ALOGE("requested param size too big");
Marco Nelissenf7a38822016-02-22 13:05:15 -0800753 } else {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800754 allocSize = (size + pageSize * 2) & ~(pageSize - 1);
755 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
756 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
757 }
758 if (params != MAP_FAILED) {
759 err = data.read(params, size);
760 if (err != OK) {
761 android_errorWriteLog(0x534e4554, "26914474");
762 } else {
763 err = NOT_ENOUGH_DATA;
764 OMX_U32 declaredSize = *(OMX_U32*)params;
Marco Nelissenc1c50e72016-03-10 15:02:13 -0800765 if (code != SET_INTERNAL_OPTION &&
766 index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits &&
767 declaredSize > size) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800768 // the buffer says it's bigger than it actually is
769 ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
770 android_errorWriteLog(0x534e4554, "27207275");
771 } else {
772 // mark the last page as inaccessible, to avoid exploitation
773 // of codecs that access past the end of the allocation because
774 // they didn't check the size
775 mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE);
776 switch (code) {
777 case GET_PARAMETER:
778 err = getParameter(node, index, params, size);
779 break;
780 case SET_PARAMETER:
781 err = setParameter(node, index, params, size);
782 break;
783 case GET_CONFIG:
784 err = getConfig(node, index, params, size);
785 break;
786 case SET_CONFIG:
787 err = setConfig(node, index, params, size);
788 break;
789 case SET_INTERNAL_OPTION:
790 {
791 InternalOptionType type =
792 (InternalOptionType)data.readInt32();
Andreas Huberb3912902011-01-19 10:34:52 -0800793
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800794 err = setInternalOption(node, index, type, params, size);
795 break;
796 }
797
798 default:
799 TRESPASS();
800 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800801 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800802 }
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800803 } else {
804 ALOGE("couldn't map: %s", strerror(errno));
Andreas Hubere40cda72013-07-17 13:55:26 -0700805 }
Andreas Huberb3912902011-01-19 10:34:52 -0800806 }
807
808 reply->writeInt32(err);
809
810 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
811 reply->write(params, size);
812 }
813
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800814 if (params) {
815 munmap(params, allocSize);
816 }
Andreas Huberb3912902011-01-19 10:34:52 -0800817 params = NULL;
Andreas Huber693d2712009-08-14 14:37:10 -0700818
819 return NO_ERROR;
820 }
821
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700822 case GET_STATE:
823 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800824 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700825
Andy Hung609b8152014-05-02 11:05:04 -0700826 node_id node = (node_id)data.readInt32();
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700827 OMX_STATETYPE state = OMX_StateInvalid;
828
829 status_t err = getState(node, &state);
830 reply->writeInt32(state);
831 reply->writeInt32(err);
832
833 return NO_ERROR;
834 }
835
Lajos Molnara63141a2016-02-11 16:40:36 -0800836 case ENABLE_NATIVE_BUFFERS:
Jamie Gennis83750ea2010-08-30 16:48:38 -0700837 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800838 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700839
Andy Hung609b8152014-05-02 11:05:04 -0700840 node_id node = (node_id)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700841 OMX_U32 port_index = data.readInt32();
Lajos Molnara63141a2016-02-11 16:40:36 -0800842 OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700843 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
844
Lajos Molnara63141a2016-02-11 16:40:36 -0800845 status_t err = enableNativeBuffers(node, port_index, graphic, enable);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700846 reply->writeInt32(err);
847
848 return NO_ERROR;
849 }
850
Jamie Gennise2ce6452011-02-23 19:01:28 -0800851 case GET_GRAPHIC_BUFFER_USAGE:
852 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800853 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800854
Andy Hung609b8152014-05-02 11:05:04 -0700855 node_id node = (node_id)data.readInt32();
Jamie Gennise2ce6452011-02-23 19:01:28 -0800856 OMX_U32 port_index = data.readInt32();
857
858 OMX_U32 usage = 0;
859 status_t err = getGraphicBufferUsage(node, port_index, &usage);
860 reply->writeInt32(err);
861 reply->writeInt32(usage);
862
863 return NO_ERROR;
864 }
865
Andreas Huber20111aa2009-07-14 16:56:47 -0700866 case USE_BUFFER:
867 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800868 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700869
Andy Hung609b8152014-05-02 11:05:04 -0700870 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700871 OMX_U32 port_index = data.readInt32();
872 sp<IMemory> params =
873 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700874 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700875
Wei Jia56c95c92016-01-06 10:30:46 -0800876 if (params == NULL) {
877 ALOGE("b/26392700");
878 reply->writeInt32(INVALID_OPERATION);
879 return NO_ERROR;
880 }
881
Andreas Huber20111aa2009-07-14 16:56:47 -0700882 buffer_id buffer;
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700883 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700884 reply->writeInt32(err);
885
886 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700887 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700888 }
889
890 return NO_ERROR;
891 }
892
Jamie Gennis83750ea2010-08-30 16:48:38 -0700893 case USE_GRAPHIC_BUFFER:
894 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800895 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700896
Andy Hung609b8152014-05-02 11:05:04 -0700897 node_id node = (node_id)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700898 OMX_U32 port_index = data.readInt32();
899 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
900 data.read(*graphicBuffer);
901
902 buffer_id buffer;
903 status_t err = useGraphicBuffer(
904 node, port_index, graphicBuffer, &buffer);
905 reply->writeInt32(err);
906
907 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700908 reply->writeInt32((int32_t)buffer);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700909 }
910
911 return NO_ERROR;
912 }
913
Lajos Molnard0715862013-07-22 12:57:43 -0700914 case UPDATE_GRAPHIC_BUFFER_IN_META:
915 {
916 CHECK_OMX_INTERFACE(IOMX, data, reply);
917
Andy Hung609b8152014-05-02 11:05:04 -0700918 node_id node = (node_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700919 OMX_U32 port_index = data.readInt32();
920 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
921 data.read(*graphicBuffer);
Andy Hung609b8152014-05-02 11:05:04 -0700922 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700923
924 status_t err = updateGraphicBufferInMeta(
925 node, port_index, graphicBuffer, buffer);
926 reply->writeInt32(err);
927
928 return NO_ERROR;
929 }
930
Lajos Molnar7e0bef82016-05-09 10:48:30 -0700931 case UPDATE_NATIVE_HANDLE_IN_META:
932 {
933 CHECK_OMX_INTERFACE(IOMX, data, reply);
934
935 node_id node = (node_id)data.readInt32();
936 OMX_U32 port_index = data.readInt32();
937 native_handle *handle = NULL;
938 if (data.readInt32()) {
939 handle = data.readNativeHandle();
940 }
941 buffer_id buffer = (buffer_id)data.readInt32();
942
943 status_t err = updateNativeHandleInMeta(
944 node, port_index, NativeHandle::create(handle, true /* ownshandle */), buffer);
945 reply->writeInt32(err);
946
947 return NO_ERROR;
948 }
949
Andy McFadden7cd58532013-02-19 07:28:30 -0800950 case CREATE_INPUT_SURFACE:
951 {
952 CHECK_OMX_INTERFACE(IOMX, data, reply);
953
Andy Hung609b8152014-05-02 11:05:04 -0700954 node_id node = (node_id)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800955 OMX_U32 port_index = data.readInt32();
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800956 android_dataspace dataSpace = (android_dataspace)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800957
958 sp<IGraphicBufferProducer> bufferProducer;
mspector@google.comda9ca912016-02-08 17:07:06 -0800959 MetadataBufferType type = kMetadataBufferTypeInvalid;
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800960 status_t err = createInputSurface(node, port_index, dataSpace, &bufferProducer, &type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800961
mspector@google.comda9ca912016-02-08 17:07:06 -0800962 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
963 android_errorWriteLog(0x534e4554, "26324358");
964 }
965
Lajos Molnar05421982015-05-15 20:39:14 -0700966 reply->writeInt32(type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800967 reply->writeInt32(err);
968
969 if (err == OK) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800970 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
Andy McFadden7cd58532013-02-19 07:28:30 -0800971 }
972
973 return NO_ERROR;
974 }
975
Chong Zhangd291c222015-04-30 18:15:52 -0700976 case CREATE_PERSISTENT_INPUT_SURFACE:
977 {
978 CHECK_OMX_INTERFACE(IOMX, data, reply);
979
980 sp<IGraphicBufferProducer> bufferProducer;
981 sp<IGraphicBufferConsumer> bufferConsumer;
982 status_t err = createPersistentInputSurface(
983 &bufferProducer, &bufferConsumer);
984
985 reply->writeInt32(err);
986
987 if (err == OK) {
988 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
989 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
990 }
991
992 return NO_ERROR;
993 }
994
Chong Zhang8f469e12015-05-13 10:21:33 -0700995 case SET_INPUT_SURFACE:
Chong Zhangd291c222015-04-30 18:15:52 -0700996 {
997 CHECK_OMX_INTERFACE(IOMX, data, reply);
998
999 node_id node = (node_id)data.readInt32();
1000 OMX_U32 port_index = data.readInt32();
1001
1002 sp<IGraphicBufferConsumer> bufferConsumer =
1003 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
1004
Wei Jia56c95c92016-01-06 10:30:46 -08001005 MetadataBufferType type = kMetadataBufferTypeInvalid;
Chong Zhangd291c222015-04-30 18:15:52 -07001006
Wei Jia56c95c92016-01-06 10:30:46 -08001007 status_t err = INVALID_OPERATION;
1008 if (bufferConsumer == NULL) {
1009 ALOGE("b/26392700");
1010 } else {
1011 err = setInputSurface(node, port_index, bufferConsumer, &type);
mspector@google.comc3ed9d02016-02-18 19:52:08 -08001012
1013 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
1014 android_errorWriteLog(0x534e4554, "26324358");
1015 }
Wei Jia56c95c92016-01-06 10:30:46 -08001016 }
Chong Zhangd291c222015-04-30 18:15:52 -07001017
Lajos Molnar05421982015-05-15 20:39:14 -07001018 reply->writeInt32(type);
Chong Zhangd291c222015-04-30 18:15:52 -07001019 reply->writeInt32(err);
1020 return NO_ERROR;
1021 }
1022
Andy McFadden7cd58532013-02-19 07:28:30 -08001023 case SIGNAL_END_OF_INPUT_STREAM:
1024 {
1025 CHECK_OMX_INTERFACE(IOMX, data, reply);
1026
Andy Hung609b8152014-05-02 11:05:04 -07001027 node_id node = (node_id)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -08001028
1029 status_t err = signalEndOfInputStream(node);
1030 reply->writeInt32(err);
1031
1032 return NO_ERROR;
1033 }
1034
James Donge8707722010-10-20 17:38:41 -07001035 case STORE_META_DATA_IN_BUFFERS:
1036 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001037 CHECK_OMX_INTERFACE(IOMX, data, reply);
James Donge8707722010-10-20 17:38:41 -07001038
Andy Hung609b8152014-05-02 11:05:04 -07001039 node_id node = (node_id)data.readInt32();
James Donge8707722010-10-20 17:38:41 -07001040 OMX_U32 port_index = data.readInt32();
1041 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1042
mspector@google.comda9ca912016-02-08 17:07:06 -08001043 MetadataBufferType type = kMetadataBufferTypeInvalid;
Lajos Molnar05421982015-05-15 20:39:14 -07001044 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
mspector@google.comda9ca912016-02-08 17:07:06 -08001045
Lajos Molnar05421982015-05-15 20:39:14 -07001046 reply->writeInt32(type);
James Donge8707722010-10-20 17:38:41 -07001047 reply->writeInt32(err);
1048
1049 return NO_ERROR;
1050 }
1051
Lajos Molnar56ce7262013-05-02 16:30:48 -07001052 case PREPARE_FOR_ADAPTIVE_PLAYBACK:
1053 {
1054 CHECK_OMX_INTERFACE(IOMX, data, reply);
1055
Andy Hung609b8152014-05-02 11:05:04 -07001056 node_id node = (node_id)data.readInt32();
Lajos Molnar56ce7262013-05-02 16:30:48 -07001057 OMX_U32 port_index = data.readInt32();
1058 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1059 OMX_U32 max_width = data.readInt32();
1060 OMX_U32 max_height = data.readInt32();
1061
1062 status_t err = prepareForAdaptivePlayback(
1063 node, port_index, enable, max_width, max_height);
1064 reply->writeInt32(err);
1065
1066 return NO_ERROR;
1067 }
1068
Rachad5a446aa2014-07-29 16:47:56 -07001069 case CONFIGURE_VIDEO_TUNNEL_MODE:
1070 {
1071 CHECK_OMX_INTERFACE(IOMX, data, reply);
1072
1073 node_id node = (node_id)data.readInt32();
1074 OMX_U32 port_index = data.readInt32();
1075 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
1076 OMX_U32 audio_hw_sync = data.readInt32();
1077
Lajos Molnara63141a2016-02-11 16:40:36 -08001078 native_handle_t *sideband_handle = NULL;
Rachad5a446aa2014-07-29 16:47:56 -07001079 status_t err = configureVideoTunnelMode(
1080 node, port_index, tunneled, audio_hw_sync, &sideband_handle);
1081 reply->writeInt32(err);
mspector@google.com9d72eb02016-02-08 10:56:13 -08001082 if(err == OK){
1083 reply->writeNativeHandle(sideband_handle);
1084 }
Rachad5a446aa2014-07-29 16:47:56 -07001085
1086 return NO_ERROR;
1087 }
1088
Lajos Molnara63141a2016-02-11 16:40:36 -08001089 case ALLOC_SECURE_BUFFER:
Andreas Huber20111aa2009-07-14 16:56:47 -07001090 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001091 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001092
Andy Hung609b8152014-05-02 11:05:04 -07001093 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001094 OMX_U32 port_index = data.readInt32();
Wei Jia8dde7262015-09-28 11:32:23 -07001095 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
1096 ALOGE("b/24310423");
1097 reply->writeInt32(INVALID_OPERATION);
1098 return NO_ERROR;
1099 }
1100
Glenn Kastene03dd222014-01-28 11:04:39 -08001101 size_t size = data.readInt64();
Andreas Huber20111aa2009-07-14 16:56:47 -07001102
1103 buffer_id buffer;
Lajos Molnara63141a2016-02-11 16:40:36 -08001104 void *buffer_data = NULL;
1105 native_handle_t *native_handle = NULL;
1106 status_t err = allocateSecureBuffer(
1107 node, port_index, size, &buffer, &buffer_data, &native_handle);
Andreas Huber20111aa2009-07-14 16:56:47 -07001108 reply->writeInt32(err);
1109
1110 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001111 reply->writeInt32((int32_t)buffer);
1112 reply->writeInt64((uintptr_t)buffer_data);
Lajos Molnara63141a2016-02-11 16:40:36 -08001113 if (buffer_data == NULL) {
1114 reply->writeNativeHandle(native_handle);
1115 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001116 }
1117
1118 return NO_ERROR;
1119 }
1120
1121 case ALLOC_BUFFER_WITH_BACKUP:
1122 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001123 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001124
Andy Hung609b8152014-05-02 11:05:04 -07001125 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001126 OMX_U32 port_index = data.readInt32();
1127 sp<IMemory> params =
1128 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001129 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001130
Wei Jia56c95c92016-01-06 10:30:46 -08001131 if (params == NULL) {
1132 ALOGE("b/26392700");
1133 reply->writeInt32(INVALID_OPERATION);
1134 return NO_ERROR;
1135 }
1136
Andreas Huber20111aa2009-07-14 16:56:47 -07001137 buffer_id buffer;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001138 status_t err = allocateBufferWithBackup(
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001139 node, port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -07001140
1141 reply->writeInt32(err);
1142
1143 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001144 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -07001145 }
1146
1147 return NO_ERROR;
1148 }
1149
1150 case FREE_BUFFER:
1151 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001152 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001153
Andy Hung609b8152014-05-02 11:05:04 -07001154 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001155 OMX_U32 port_index = data.readInt32();
Andy Hung609b8152014-05-02 11:05:04 -07001156 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -07001157 reply->writeInt32(freeBuffer(node, port_index, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -07001158
1159 return NO_ERROR;
1160 }
1161
1162 case FILL_BUFFER:
1163 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001164 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001165
Andy Hung609b8152014-05-02 11:05:04 -07001166 node_id node = (node_id)data.readInt32();
1167 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001168 bool haveFence = data.readInt32();
1169 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1170 reply->writeInt32(fillBuffer(node, buffer, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001171
1172 return NO_ERROR;
1173 }
1174
1175 case EMPTY_BUFFER:
1176 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001177 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001178
Andy Hung609b8152014-05-02 11:05:04 -07001179 node_id node = (node_id)data.readInt32();
1180 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001181 OMX_U32 range_offset = data.readInt32();
1182 OMX_U32 range_length = data.readInt32();
1183 OMX_U32 flags = data.readInt32();
1184 OMX_TICKS timestamp = data.readInt64();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001185 bool haveFence = data.readInt32();
1186 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1187 reply->writeInt32(emptyBuffer(
1188 node, buffer, range_offset, range_length, flags, timestamp, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001189
1190 return NO_ERROR;
1191 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001192
Andreas Huber693d2712009-08-14 14:37:10 -07001193 case GET_EXTENSION_INDEX:
1194 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001195 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -07001196
Andy Hung609b8152014-05-02 11:05:04 -07001197 node_id node = (node_id)data.readInt32();
Andreas Huber693d2712009-08-14 14:37:10 -07001198 const char *parameter_name = data.readCString();
Andreas Huber7eaa9c92010-01-15 15:28:19 -08001199
Wei Jia56c95c92016-01-06 10:30:46 -08001200 if (parameter_name == NULL) {
1201 ALOGE("b/26392700");
1202 reply->writeInt32(INVALID_OPERATION);
1203 return NO_ERROR;
1204 }
1205
Andreas Huber693d2712009-08-14 14:37:10 -07001206 OMX_INDEXTYPE index;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001207 status_t err = getExtensionIndex(node, parameter_name, &index);
Andreas Huber693d2712009-08-14 14:37:10 -07001208
1209 reply->writeInt32(err);
1210
1211 if (err == OK) {
1212 reply->writeInt32(index);
1213 }
1214
1215 return OK;
1216 }
1217
Andreas Huber20111aa2009-07-14 16:56:47 -07001218 default:
1219 return BBinder::onTransact(code, data, reply, flags);
1220 }
1221}
1222
1223////////////////////////////////////////////////////////////////////////////////
1224
1225class BpOMXObserver : public BpInterface<IOMXObserver> {
1226public:
1227 BpOMXObserver(const sp<IBinder> &impl)
1228 : BpInterface<IOMXObserver>(impl) {
1229 }
1230
Lajos Molnar26a48f32015-06-04 10:30:02 -07001231 virtual void onMessages(const std::list<omx_message> &messages) {
Andreas Huber20111aa2009-07-14 16:56:47 -07001232 Parcel data, reply;
Lajos Molnar26a48f32015-06-04 10:30:02 -07001233 std::list<omx_message>::const_iterator it = messages.cbegin();
1234 bool first = true;
1235 while (it != messages.cend()) {
1236 const omx_message &msg = *it++;
1237 if (first) {
1238 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
1239 data.writeInt32(msg.node);
1240 first = false;
1241 }
1242 data.writeInt32(msg.fenceFd >= 0);
1243 if (msg.fenceFd >= 0) {
1244 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
1245 }
1246 data.writeInt32(msg.type);
1247 data.write(&msg.u, sizeof(msg.u));
1248 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
Lajos Molnar15ab4992015-06-01 10:54:31 -07001249 }
Lajos Molnar26a48f32015-06-04 10:30:02 -07001250 if (!first) {
1251 data.writeInt32(-1); // mark end
1252 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
1253 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001254 }
1255};
1256
1257IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
1258
1259status_t BnOMXObserver::onTransact(
1260 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
1261 switch (code) {
1262 case OBSERVER_ON_MSG:
1263 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001264 CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
Lajos Molnar26a48f32015-06-04 10:30:02 -07001265 IOMX::node_id node = data.readInt32();
1266 std::list<omx_message> messages;
1267 status_t err = FAILED_TRANSACTION; // must receive at least one message
1268 do {
1269 int haveFence = data.readInt32();
1270 if (haveFence < 0) { // we use -1 to mark end of messages
1271 break;
1272 }
1273 omx_message msg;
1274 msg.node = node;
1275 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1276 msg.type = (typeof(msg.type))data.readInt32();
1277 err = data.read(&msg.u, sizeof(msg.u));
1278 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
1279 messages.push_back(msg);
1280 } while (err == OK);
Andreas Huber20111aa2009-07-14 16:56:47 -07001281
Lajos Molnar26a48f32015-06-04 10:30:02 -07001282 if (err == OK) {
1283 onMessages(messages);
Lajos Molnar15ab4992015-06-01 10:54:31 -07001284 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001285
Lajos Molnar26a48f32015-06-04 10:30:02 -07001286 return err;
Andreas Huber20111aa2009-07-14 16:56:47 -07001287 }
1288
1289 default:
1290 return BBinder::onTransact(code, data, reply, flags);
1291 }
1292}
1293
Andreas Huber20111aa2009-07-14 16:56:47 -07001294} // namespace android