blob: b1d38b60d2301540055109647ac6aa67866d1d2d [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 Molnar1b40f282016-05-09 22:24:52 -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,
Andreas Huber20111aa2009-07-14 16:56:47 -070064};
65
Andreas Huber20111aa2009-07-14 16:56:47 -070066class BpOMX : public BpInterface<IOMX> {
67public:
68 BpOMX(const sp<IBinder> &impl)
69 : BpInterface<IOMX>(impl) {
70 }
71
Andreas Huberd459b482012-01-31 11:16:24 -080072 virtual bool livesLocally(node_id node, pid_t pid) {
Andreas Huber7eaa9c92010-01-15 15:28:19 -080073 Parcel data, reply;
74 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -070075 data.writeInt32((int32_t)node);
Andreas Huber7eaa9c92010-01-15 15:28:19 -080076 data.writeInt32(pid);
77 remote()->transact(LIVES_LOCALLY, data, &reply);
78
79 return reply.readInt32() != 0;
80 }
81
Andreas Huber134ee6a2009-12-16 09:30:55 -080082 virtual status_t listNodes(List<ComponentInfo> *list) {
Andreas Huber20111aa2009-07-14 16:56:47 -070083 list->clear();
84
85 Parcel data, reply;
86 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
87 remote()->transact(LIST_NODES, data, &reply);
88
89 int32_t n = reply.readInt32();
90 for (int32_t i = 0; i < n; ++i) {
Andreas Huber134ee6a2009-12-16 09:30:55 -080091 list->push_back(ComponentInfo());
92 ComponentInfo &info = *--list->end();
Andreas Huber20111aa2009-07-14 16:56:47 -070093
Andreas Huber134ee6a2009-12-16 09:30:55 -080094 info.mName = reply.readString8();
95 int32_t numRoles = reply.readInt32();
96 for (int32_t j = 0; j < numRoles; ++j) {
97 info.mRoles.push_back(reply.readString8());
98 }
Andreas Huber20111aa2009-07-14 16:56:47 -070099 }
100
101 return OK;
102 }
103
Andreas Huber318ad9c2009-10-15 13:46:54 -0700104 virtual status_t allocateNode(
Marco Nelissen23858872016-02-17 13:12:13 -0800105 const char *name, const sp<IOMXObserver> &observer,
106 sp<IBinder> *nodeBinder,
107 node_id *node) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700108 Parcel data, reply;
109 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
110 data.writeCString(name);
Marco Nelissen06b46062014-11-14 07:58:25 -0800111 data.writeStrongBinder(IInterface::asBinder(observer));
Andreas Huber20111aa2009-07-14 16:56:47 -0700112 remote()->transact(ALLOCATE_NODE, data, &reply);
113
114 status_t err = reply.readInt32();
115 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700116 *node = (node_id)reply.readInt32();
Marco Nelissen23858872016-02-17 13:12:13 -0800117 if (nodeBinder != NULL) {
118 *nodeBinder = remote();
119 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700120 } else {
121 *node = 0;
122 }
123
124 return err;
125 }
126
Andreas Huber318ad9c2009-10-15 13:46:54 -0700127 virtual status_t freeNode(node_id node) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700128 Parcel data, reply;
129 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700130 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700131 remote()->transact(FREE_NODE, data, &reply);
132
133 return reply.readInt32();
134 }
135
Andreas Huber318ad9c2009-10-15 13:46:54 -0700136 virtual status_t sendCommand(
Andreas Huber20111aa2009-07-14 16:56:47 -0700137 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
138 Parcel data, reply;
139 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700140 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700141 data.writeInt32(cmd);
142 data.writeInt32(param);
143 remote()->transact(SEND_COMMAND, data, &reply);
144
145 return reply.readInt32();
146 }
147
Andreas Huber318ad9c2009-10-15 13:46:54 -0700148 virtual status_t getParameter(
Andreas Huber20111aa2009-07-14 16:56:47 -0700149 node_id node, OMX_INDEXTYPE index,
150 void *params, size_t size) {
151 Parcel data, reply;
152 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700153 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700154 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800155 data.writeInt64(size);
Andreas Huber20111aa2009-07-14 16:56:47 -0700156 data.write(params, size);
157 remote()->transact(GET_PARAMETER, data, &reply);
158
159 status_t err = reply.readInt32();
160 if (err != OK) {
161 return err;
162 }
163
164 reply.read(params, size);
165
166 return OK;
167 }
168
Andreas Huber318ad9c2009-10-15 13:46:54 -0700169 virtual status_t setParameter(
Andreas Huber20111aa2009-07-14 16:56:47 -0700170 node_id node, OMX_INDEXTYPE index,
171 const void *params, size_t size) {
172 Parcel data, reply;
173 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700174 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700175 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800176 data.writeInt64(size);
Andreas Huber20111aa2009-07-14 16:56:47 -0700177 data.write(params, size);
178 remote()->transact(SET_PARAMETER, data, &reply);
179
180 return reply.readInt32();
181 }
182
Andreas Huber318ad9c2009-10-15 13:46:54 -0700183 virtual status_t getConfig(
Andreas Huber693d2712009-08-14 14:37:10 -0700184 node_id node, OMX_INDEXTYPE index,
185 void *params, size_t size) {
186 Parcel data, reply;
187 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700188 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700189 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800190 data.writeInt64(size);
Andreas Huber693d2712009-08-14 14:37:10 -0700191 data.write(params, size);
192 remote()->transact(GET_CONFIG, data, &reply);
193
194 status_t err = reply.readInt32();
195 if (err != OK) {
196 return err;
197 }
198
199 reply.read(params, size);
200
201 return OK;
202 }
203
Andreas Huber318ad9c2009-10-15 13:46:54 -0700204 virtual status_t setConfig(
Andreas Huber693d2712009-08-14 14:37:10 -0700205 node_id node, OMX_INDEXTYPE index,
206 const void *params, size_t size) {
207 Parcel data, reply;
208 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700209 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700210 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800211 data.writeInt64(size);
Andreas Huber693d2712009-08-14 14:37:10 -0700212 data.write(params, size);
213 remote()->transact(SET_CONFIG, data, &reply);
214
215 return reply.readInt32();
216 }
217
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700218 virtual status_t getState(
219 node_id node, OMX_STATETYPE* state) {
220 Parcel data, reply;
221 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700222 data.writeInt32((int32_t)node);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700223 remote()->transact(GET_STATE, data, &reply);
224
225 *state = static_cast<OMX_STATETYPE>(reply.readInt32());
226 return reply.readInt32();
227 }
228
Lajos Molnara63141a2016-02-11 16:40:36 -0800229 virtual status_t enableNativeBuffers(
230 node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
Jamie Gennis83750ea2010-08-30 16:48:38 -0700231 Parcel data, reply;
232 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700233 data.writeInt32((int32_t)node);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700234 data.writeInt32(port_index);
Lajos Molnara63141a2016-02-11 16:40:36 -0800235 data.writeInt32((uint32_t)graphic);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700236 data.writeInt32((uint32_t)enable);
Lajos Molnara63141a2016-02-11 16:40:36 -0800237 remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700238
239 status_t err = reply.readInt32();
240 return err;
241 }
242
Jamie Gennise2ce6452011-02-23 19:01:28 -0800243 virtual status_t getGraphicBufferUsage(
244 node_id node, OMX_U32 port_index, OMX_U32* usage) {
245 Parcel data, reply;
246 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700247 data.writeInt32((int32_t)node);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800248 data.writeInt32(port_index);
249 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
250
251 status_t err = reply.readInt32();
252 *usage = reply.readInt32();
253 return err;
254 }
255
Andreas Huber318ad9c2009-10-15 13:46:54 -0700256 virtual status_t useBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700257 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700258 buffer_id *buffer, OMX_U32 allottedSize) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700259 Parcel data, reply;
260 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700261 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700262 data.writeInt32(port_index);
Marco Nelissen06b46062014-11-14 07:58:25 -0800263 data.writeStrongBinder(IInterface::asBinder(params));
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700264 data.writeInt32(allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700265 remote()->transact(USE_BUFFER, data, &reply);
266
267 status_t err = reply.readInt32();
268 if (err != OK) {
269 *buffer = 0;
270
271 return err;
272 }
273
Andy Hung609b8152014-05-02 11:05:04 -0700274 *buffer = (buffer_id)reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700275
276 return err;
277 }
278
Jamie Gennis83750ea2010-08-30 16:48:38 -0700279
280 virtual status_t useGraphicBuffer(
281 node_id node, OMX_U32 port_index,
282 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
283 Parcel data, reply;
284 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700285 data.writeInt32((int32_t)node);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700286 data.writeInt32(port_index);
287 data.write(*graphicBuffer);
288 remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
289
290 status_t err = reply.readInt32();
291 if (err != OK) {
292 *buffer = 0;
293
294 return err;
295 }
296
Andy Hung609b8152014-05-02 11:05:04 -0700297 *buffer = (buffer_id)reply.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700298
299 return err;
300 }
301
Lajos Molnard0715862013-07-22 12:57:43 -0700302 virtual status_t updateGraphicBufferInMeta(
303 node_id node, OMX_U32 port_index,
304 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
305 Parcel data, reply;
306 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700307 data.writeInt32((int32_t)node);
Lajos Molnard0715862013-07-22 12:57:43 -0700308 data.writeInt32(port_index);
309 data.write(*graphicBuffer);
Andy Hung609b8152014-05-02 11:05:04 -0700310 data.writeInt32((int32_t)buffer);
Lajos Molnard0715862013-07-22 12:57:43 -0700311 remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
312
313 status_t err = reply.readInt32();
314 return err;
315 }
316
Andy McFadden7cd58532013-02-19 07:28:30 -0800317 virtual status_t createInputSurface(
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800318 node_id node, OMX_U32 port_index, android_dataspace dataSpace,
Lajos Molnar05421982015-05-15 20:39:14 -0700319 sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
Andy McFadden7cd58532013-02-19 07:28:30 -0800320 Parcel data, reply;
321 status_t err;
322 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700323 data.writeInt32((int32_t)node);
Andy McFadden7cd58532013-02-19 07:28:30 -0800324 data.writeInt32(port_index);
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800325 data.writeInt32(dataSpace);
Andy McFadden7cd58532013-02-19 07:28:30 -0800326 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
327 if (err != OK) {
328 ALOGW("binder transaction failed: %d", err);
329 return err;
330 }
331
Lajos Molnar05421982015-05-15 20:39:14 -0700332 // read type even if createInputSurface failed
333 int negotiatedType = reply.readInt32();
334 if (type != NULL) {
335 *type = (MetadataBufferType)negotiatedType;
336 }
337
Andy McFadden7cd58532013-02-19 07:28:30 -0800338 err = reply.readInt32();
339 if (err != OK) {
340 return err;
341 }
342
343 *bufferProducer = IGraphicBufferProducer::asInterface(
344 reply.readStrongBinder());
345
346 return err;
347 }
348
Chong Zhangd291c222015-04-30 18:15:52 -0700349 virtual status_t createPersistentInputSurface(
350 sp<IGraphicBufferProducer> *bufferProducer,
351 sp<IGraphicBufferConsumer> *bufferConsumer) {
352 Parcel data, reply;
353 status_t err;
354 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
355 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply);
356 if (err != OK) {
357 ALOGW("binder transaction failed: %d", err);
358 return err;
359 }
360
361 err = reply.readInt32();
362 if (err != OK) {
363 return err;
364 }
365
366 *bufferProducer = IGraphicBufferProducer::asInterface(
367 reply.readStrongBinder());
368 *bufferConsumer = IGraphicBufferConsumer::asInterface(
369 reply.readStrongBinder());
370
371 return err;
372 }
373
Chong Zhang8f469e12015-05-13 10:21:33 -0700374 virtual status_t setInputSurface(
Chong Zhangd291c222015-04-30 18:15:52 -0700375 node_id node, OMX_U32 port_index,
Lajos Molnar05421982015-05-15 20:39:14 -0700376 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) {
Chong Zhangd291c222015-04-30 18:15:52 -0700377 Parcel data, reply;
378 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
379 status_t err;
380 data.writeInt32((int32_t)node);
381 data.writeInt32(port_index);
382 data.writeStrongBinder(IInterface::asBinder(bufferConsumer));
383
Chong Zhang8f469e12015-05-13 10:21:33 -0700384 err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
Chong Zhangd291c222015-04-30 18:15:52 -0700385
386 if (err != OK) {
387 ALOGW("binder transaction failed: %d", err);
388 return err;
389 }
Lajos Molnar05421982015-05-15 20:39:14 -0700390
391 // read type even if setInputSurface failed
392 int negotiatedType = reply.readInt32();
393 if (type != NULL) {
394 *type = (MetadataBufferType)negotiatedType;
395 }
396
Chong Zhangd291c222015-04-30 18:15:52 -0700397 return reply.readInt32();
398 }
399
Andy McFadden7cd58532013-02-19 07:28:30 -0800400 virtual status_t signalEndOfInputStream(node_id node) {
401 Parcel data, reply;
402 status_t err;
403 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700404 data.writeInt32((int32_t)node);
Andy McFadden7cd58532013-02-19 07:28:30 -0800405 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply);
406 if (err != OK) {
407 ALOGW("binder transaction failed: %d", err);
408 return err;
409 }
410
411 return reply.readInt32();
412 }
413
James Donge8707722010-10-20 17:38:41 -0700414 virtual status_t storeMetaDataInBuffers(
Lajos Molnar05421982015-05-15 20:39:14 -0700415 node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
James Donge8707722010-10-20 17:38:41 -0700416 Parcel data, reply;
417 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700418 data.writeInt32((int32_t)node);
James Donge8707722010-10-20 17:38:41 -0700419 data.writeInt32(port_index);
420 data.writeInt32((uint32_t)enable);
421 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
422
Lajos Molnar05421982015-05-15 20:39:14 -0700423 // read type even storeMetaDataInBuffers failed
424 int negotiatedType = reply.readInt32();
425 if (type != NULL) {
426 *type = (MetadataBufferType)negotiatedType;
427 }
428
429 return reply.readInt32();
James Donge8707722010-10-20 17:38:41 -0700430 }
431
Lajos Molnar56ce7262013-05-02 16:30:48 -0700432 virtual status_t prepareForAdaptivePlayback(
433 node_id node, OMX_U32 port_index, OMX_BOOL enable,
434 OMX_U32 max_width, OMX_U32 max_height) {
435 Parcel data, reply;
436 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700437 data.writeInt32((int32_t)node);
Lajos Molnar56ce7262013-05-02 16:30:48 -0700438 data.writeInt32(port_index);
439 data.writeInt32((int32_t)enable);
440 data.writeInt32(max_width);
441 data.writeInt32(max_height);
442 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
443
444 status_t err = reply.readInt32();
445 return err;
446 }
447
Rachad5a446aa2014-07-29 16:47:56 -0700448 virtual status_t configureVideoTunnelMode(
449 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
450 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
451 Parcel data, reply;
452 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
453 data.writeInt32((int32_t)node);
454 data.writeInt32(portIndex);
455 data.writeInt32((int32_t)tunneled);
456 data.writeInt32(audioHwSync);
457 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
458
459 status_t err = reply.readInt32();
mspector@google.com9d72eb02016-02-08 10:56:13 -0800460 if (err == OK && sidebandHandle) {
Rachad5a446aa2014-07-29 16:47:56 -0700461 *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
462 }
463 return err;
464 }
465
466
Lajos Molnara63141a2016-02-11 16:40:36 -0800467 virtual status_t allocateSecureBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700468 node_id node, OMX_U32 port_index, size_t size,
Lajos Molnar1b40f282016-05-09 22:24:52 -0700469 buffer_id *buffer, void **buffer_data, sp<NativeHandle> *native_handle) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700470 Parcel data, reply;
471 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700472 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700473 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800474 data.writeInt64(size);
Lajos Molnara63141a2016-02-11 16:40:36 -0800475 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700476
477 status_t err = reply.readInt32();
478 if (err != OK) {
479 *buffer = 0;
Lajos Molnara63141a2016-02-11 16:40:36 -0800480 *buffer_data = NULL;
481 *native_handle = NULL;
Andreas Huber20111aa2009-07-14 16:56:47 -0700482 return err;
483 }
484
Andy Hung609b8152014-05-02 11:05:04 -0700485 *buffer = (buffer_id)reply.readInt32();
486 *buffer_data = (void *)reply.readInt64();
Lajos Molnara63141a2016-02-11 16:40:36 -0800487 if (*buffer_data == NULL) {
Lajos Molnar1b40f282016-05-09 22:24:52 -0700488 *native_handle = NativeHandle::create(
489 reply.readNativeHandle(), true /* ownsHandle */);
Lajos Molnara63141a2016-02-11 16:40:36 -0800490 } else {
491 *native_handle = NULL;
492 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700493 return err;
494 }
495
Andreas Huber318ad9c2009-10-15 13:46:54 -0700496 virtual status_t allocateBufferWithBackup(
Andreas Huber20111aa2009-07-14 16:56:47 -0700497 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700498 buffer_id *buffer, OMX_U32 allottedSize) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700499 Parcel data, reply;
500 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700501 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700502 data.writeInt32(port_index);
Marco Nelissen06b46062014-11-14 07:58:25 -0800503 data.writeStrongBinder(IInterface::asBinder(params));
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700504 data.writeInt32(allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700505 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
506
507 status_t err = reply.readInt32();
508 if (err != OK) {
509 *buffer = 0;
510
511 return err;
512 }
513
Andy Hung609b8152014-05-02 11:05:04 -0700514 *buffer = (buffer_id)reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700515
516 return err;
517 }
518
Andreas Huber318ad9c2009-10-15 13:46:54 -0700519 virtual status_t freeBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700520 node_id node, OMX_U32 port_index, buffer_id buffer) {
521 Parcel data, reply;
522 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700523 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700524 data.writeInt32(port_index);
Andy Hung609b8152014-05-02 11:05:04 -0700525 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700526 remote()->transact(FREE_BUFFER, data, &reply);
527
528 return reply.readInt32();
529 }
530
Lajos Molnar15ab4992015-06-01 10:54:31 -0700531 virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700532 Parcel data, reply;
533 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700534 data.writeInt32((int32_t)node);
535 data.writeInt32((int32_t)buffer);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700536 data.writeInt32(fenceFd >= 0);
537 if (fenceFd >= 0) {
538 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
539 }
Andreas Huber36efa032009-10-08 11:02:27 -0700540 remote()->transact(FILL_BUFFER, data, &reply);
541
542 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700543 }
544
Andreas Huber318ad9c2009-10-15 13:46:54 -0700545 virtual status_t emptyBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700546 node_id node,
547 buffer_id buffer,
548 OMX_U32 range_offset, OMX_U32 range_length,
Lajos Molnar15ab4992015-06-01 10:54:31 -0700549 OMX_U32 flags, OMX_TICKS timestamp, 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);
Andreas Huber20111aa2009-07-14 16:56:47 -0700554 data.writeInt32(range_offset);
555 data.writeInt32(range_length);
556 data.writeInt32(flags);
557 data.writeInt64(timestamp);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700558 data.writeInt32(fenceFd >= 0);
559 if (fenceFd >= 0) {
560 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
561 }
Andreas Huber36efa032009-10-08 11:02:27 -0700562 remote()->transact(EMPTY_BUFFER, data, &reply);
563
564 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700565 }
Andreas Huber8b938cd2009-07-31 11:52:50 -0700566
Andreas Huber318ad9c2009-10-15 13:46:54 -0700567 virtual status_t getExtensionIndex(
Andreas Huber693d2712009-08-14 14:37:10 -0700568 node_id node,
569 const char *parameter_name,
570 OMX_INDEXTYPE *index) {
571 Parcel data, reply;
572 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700573 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700574 data.writeCString(parameter_name);
575
576 remote()->transact(GET_EXTENSION_INDEX, data, &reply);
577
578 status_t err = reply.readInt32();
579 if (err == OK) {
580 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
581 } else {
582 *index = OMX_IndexComponentStartUnused;
583 }
584
585 return err;
586 }
Andreas Hubere40cda72013-07-17 13:55:26 -0700587
588 virtual status_t setInternalOption(
589 node_id node,
590 OMX_U32 port_index,
591 InternalOptionType type,
592 const void *optionData,
593 size_t size) {
594 Parcel data, reply;
595 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700596 data.writeInt32((int32_t)node);
Andreas Hubere40cda72013-07-17 13:55:26 -0700597 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800598 data.writeInt64(size);
Andreas Hubere40cda72013-07-17 13:55:26 -0700599 data.write(optionData, size);
600 data.writeInt32(type);
601 remote()->transact(SET_INTERNAL_OPTION, data, &reply);
602
603 return reply.readInt32();
604 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700605};
606
607IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
608
609////////////////////////////////////////////////////////////////////////////////
610
Andy McFadden7cd58532013-02-19 07:28:30 -0800611#define CHECK_OMX_INTERFACE(interface, data, reply) \
Andreas Huber20111aa2009-07-14 16:56:47 -0700612 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
Steve Block5ff1dd52012-01-05 23:22:43 +0000613 ALOGW("Call incorrectly routed to " #interface); \
Andreas Huber20111aa2009-07-14 16:56:47 -0700614 return PERMISSION_DENIED; \
615 } } while (0)
616
617status_t BnOMX::onTransact(
618 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
619 switch (code) {
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800620 case LIVES_LOCALLY:
621 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800622 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andy Hung609b8152014-05-02 11:05:04 -0700623 node_id node = (node_id)data.readInt32();
Andreas Huberd459b482012-01-31 11:16:24 -0800624 pid_t pid = (pid_t)data.readInt32();
625 reply->writeInt32(livesLocally(node, pid));
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800626
627 return OK;
628 }
629
Andreas Huber20111aa2009-07-14 16:56:47 -0700630 case LIST_NODES:
631 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800632 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700633
Andreas Huber134ee6a2009-12-16 09:30:55 -0800634 List<ComponentInfo> list;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700635 listNodes(&list);
Andreas Huber20111aa2009-07-14 16:56:47 -0700636
637 reply->writeInt32(list.size());
Andreas Huber134ee6a2009-12-16 09:30:55 -0800638 for (List<ComponentInfo>::iterator it = list.begin();
Andreas Huber20111aa2009-07-14 16:56:47 -0700639 it != list.end(); ++it) {
Andreas Huber134ee6a2009-12-16 09:30:55 -0800640 ComponentInfo &cur = *it;
641
642 reply->writeString8(cur.mName);
643 reply->writeInt32(cur.mRoles.size());
644 for (List<String8>::iterator role_it = cur.mRoles.begin();
645 role_it != cur.mRoles.end(); ++role_it) {
646 reply->writeString8(*role_it);
647 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700648 }
649
650 return NO_ERROR;
651 }
652
653 case ALLOCATE_NODE:
654 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800655 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700656
Andreas Huber318ad9c2009-10-15 13:46:54 -0700657 const char *name = data.readCString();
658
659 sp<IOMXObserver> observer =
660 interface_cast<IOMXObserver>(data.readStrongBinder());
661
Wei Jia56c95c92016-01-06 10:30:46 -0800662 if (name == NULL || observer == NULL) {
663 ALOGE("b/26392700");
664 reply->writeInt32(INVALID_OPERATION);
665 return NO_ERROR;
666 }
667
Andreas Huber20111aa2009-07-14 16:56:47 -0700668 node_id node;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700669
Marco Nelissen23858872016-02-17 13:12:13 -0800670 status_t err = allocateNode(name, observer,
671 NULL /* nodeBinder */, &node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700672 reply->writeInt32(err);
673 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700674 reply->writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700675 }
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800676
Andreas Huber20111aa2009-07-14 16:56:47 -0700677 return NO_ERROR;
678 }
679
680 case FREE_NODE:
681 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800682 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700683
Andy Hung609b8152014-05-02 11:05:04 -0700684 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700685
Andreas Huber318ad9c2009-10-15 13:46:54 -0700686 reply->writeInt32(freeNode(node));
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800687
Andreas Huber20111aa2009-07-14 16:56:47 -0700688 return NO_ERROR;
689 }
690
691 case SEND_COMMAND:
692 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800693 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700694
Andy Hung609b8152014-05-02 11:05:04 -0700695 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700696
697 OMX_COMMANDTYPE cmd =
698 static_cast<OMX_COMMANDTYPE>(data.readInt32());
699
700 OMX_S32 param = data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -0700701 reply->writeInt32(sendCommand(node, cmd, param));
Andreas Huber20111aa2009-07-14 16:56:47 -0700702
703 return NO_ERROR;
704 }
705
706 case GET_PARAMETER:
Andreas Huber20111aa2009-07-14 16:56:47 -0700707 case SET_PARAMETER:
Andreas Huber693d2712009-08-14 14:37:10 -0700708 case GET_CONFIG:
Andreas Huber693d2712009-08-14 14:37:10 -0700709 case SET_CONFIG:
Andreas Hubere40cda72013-07-17 13:55:26 -0700710 case SET_INTERNAL_OPTION:
Andreas Huber693d2712009-08-14 14:37:10 -0700711 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800712 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -0700713
Andy Hung609b8152014-05-02 11:05:04 -0700714 node_id node = (node_id)data.readInt32();
Andreas Huber693d2712009-08-14 14:37:10 -0700715 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
716
Glenn Kastene03dd222014-01-28 11:04:39 -0800717 size_t size = data.readInt64();
Andreas Huber693d2712009-08-14 14:37:10 -0700718
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800719 status_t err = NOT_ENOUGH_DATA;
720 void *params = NULL;
721 size_t pageSize = 0;
722 size_t allocSize = 0;
Marco Nelissen788b0b62016-03-21 11:31:53 -0700723 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits);
724 if ((isUsageBits && size < 4) ||
725 (!isUsageBits && code != SET_INTERNAL_OPTION && size < 8)) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800726 // we expect the structure to contain at least the size and
727 // version, 8 bytes total
Marco Nelissen788b0b62016-03-21 11:31:53 -0700728 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code));
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800729 android_errorWriteLog(0x534e4554, "27207275");
730 } else {
731 err = NO_MEMORY;
732 pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
733 if (size > SIZE_MAX - (pageSize * 2)) {
734 ALOGE("requested param size too big");
Marco Nelissenf7a38822016-02-22 13:05:15 -0800735 } else {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800736 allocSize = (size + pageSize * 2) & ~(pageSize - 1);
737 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
738 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
739 }
740 if (params != MAP_FAILED) {
741 err = data.read(params, size);
742 if (err != OK) {
743 android_errorWriteLog(0x534e4554, "26914474");
744 } else {
745 err = NOT_ENOUGH_DATA;
746 OMX_U32 declaredSize = *(OMX_U32*)params;
Marco Nelissenc1c50e72016-03-10 15:02:13 -0800747 if (code != SET_INTERNAL_OPTION &&
748 index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits &&
749 declaredSize > size) {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800750 // the buffer says it's bigger than it actually is
751 ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
752 android_errorWriteLog(0x534e4554, "27207275");
753 } else {
754 // mark the last page as inaccessible, to avoid exploitation
755 // of codecs that access past the end of the allocation because
756 // they didn't check the size
757 mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE);
758 switch (code) {
759 case GET_PARAMETER:
760 err = getParameter(node, index, params, size);
761 break;
762 case SET_PARAMETER:
763 err = setParameter(node, index, params, size);
764 break;
765 case GET_CONFIG:
766 err = getConfig(node, index, params, size);
767 break;
768 case SET_CONFIG:
769 err = setConfig(node, index, params, size);
770 break;
771 case SET_INTERNAL_OPTION:
772 {
773 InternalOptionType type =
774 (InternalOptionType)data.readInt32();
Andreas Huberb3912902011-01-19 10:34:52 -0800775
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800776 err = setInternalOption(node, index, type, params, size);
777 break;
778 }
779
780 default:
781 TRESPASS();
782 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800783 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800784 }
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800785 } else {
786 ALOGE("couldn't map: %s", strerror(errno));
Andreas Hubere40cda72013-07-17 13:55:26 -0700787 }
Andreas Huberb3912902011-01-19 10:34:52 -0800788 }
789
790 reply->writeInt32(err);
791
792 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
793 reply->write(params, size);
794 }
795
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800796 if (params) {
797 munmap(params, allocSize);
798 }
Andreas Huberb3912902011-01-19 10:34:52 -0800799 params = NULL;
Andreas Huber693d2712009-08-14 14:37:10 -0700800
801 return NO_ERROR;
802 }
803
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700804 case GET_STATE:
805 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800806 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700807
Andy Hung609b8152014-05-02 11:05:04 -0700808 node_id node = (node_id)data.readInt32();
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700809 OMX_STATETYPE state = OMX_StateInvalid;
810
811 status_t err = getState(node, &state);
812 reply->writeInt32(state);
813 reply->writeInt32(err);
814
815 return NO_ERROR;
816 }
817
Lajos Molnara63141a2016-02-11 16:40:36 -0800818 case ENABLE_NATIVE_BUFFERS:
Jamie Gennis83750ea2010-08-30 16:48:38 -0700819 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800820 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700821
Andy Hung609b8152014-05-02 11:05:04 -0700822 node_id node = (node_id)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700823 OMX_U32 port_index = data.readInt32();
Lajos Molnara63141a2016-02-11 16:40:36 -0800824 OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700825 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
826
Lajos Molnara63141a2016-02-11 16:40:36 -0800827 status_t err = enableNativeBuffers(node, port_index, graphic, enable);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700828 reply->writeInt32(err);
829
830 return NO_ERROR;
831 }
832
Jamie Gennise2ce6452011-02-23 19:01:28 -0800833 case GET_GRAPHIC_BUFFER_USAGE:
834 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800835 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800836
Andy Hung609b8152014-05-02 11:05:04 -0700837 node_id node = (node_id)data.readInt32();
Jamie Gennise2ce6452011-02-23 19:01:28 -0800838 OMX_U32 port_index = data.readInt32();
839
840 OMX_U32 usage = 0;
841 status_t err = getGraphicBufferUsage(node, port_index, &usage);
842 reply->writeInt32(err);
843 reply->writeInt32(usage);
844
845 return NO_ERROR;
846 }
847
Andreas Huber20111aa2009-07-14 16:56:47 -0700848 case USE_BUFFER:
849 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800850 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700851
Andy Hung609b8152014-05-02 11:05:04 -0700852 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700853 OMX_U32 port_index = data.readInt32();
854 sp<IMemory> params =
855 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700856 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700857
Wei Jia56c95c92016-01-06 10:30:46 -0800858 if (params == NULL) {
859 ALOGE("b/26392700");
860 reply->writeInt32(INVALID_OPERATION);
861 return NO_ERROR;
862 }
863
Andreas Huber20111aa2009-07-14 16:56:47 -0700864 buffer_id buffer;
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700865 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700866 reply->writeInt32(err);
867
868 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700869 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700870 }
871
872 return NO_ERROR;
873 }
874
Jamie Gennis83750ea2010-08-30 16:48:38 -0700875 case USE_GRAPHIC_BUFFER:
876 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800877 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700878
Andy Hung609b8152014-05-02 11:05:04 -0700879 node_id node = (node_id)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700880 OMX_U32 port_index = data.readInt32();
881 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
882 data.read(*graphicBuffer);
883
884 buffer_id buffer;
885 status_t err = useGraphicBuffer(
886 node, port_index, graphicBuffer, &buffer);
887 reply->writeInt32(err);
888
889 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700890 reply->writeInt32((int32_t)buffer);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700891 }
892
893 return NO_ERROR;
894 }
895
Lajos Molnard0715862013-07-22 12:57:43 -0700896 case UPDATE_GRAPHIC_BUFFER_IN_META:
897 {
898 CHECK_OMX_INTERFACE(IOMX, data, reply);
899
Andy Hung609b8152014-05-02 11:05:04 -0700900 node_id node = (node_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700901 OMX_U32 port_index = data.readInt32();
902 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
903 data.read(*graphicBuffer);
Andy Hung609b8152014-05-02 11:05:04 -0700904 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700905
906 status_t err = updateGraphicBufferInMeta(
907 node, port_index, graphicBuffer, buffer);
908 reply->writeInt32(err);
909
910 return NO_ERROR;
911 }
912
Andy McFadden7cd58532013-02-19 07:28:30 -0800913 case CREATE_INPUT_SURFACE:
914 {
915 CHECK_OMX_INTERFACE(IOMX, data, reply);
916
Andy Hung609b8152014-05-02 11:05:04 -0700917 node_id node = (node_id)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800918 OMX_U32 port_index = data.readInt32();
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800919 android_dataspace dataSpace = (android_dataspace)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800920
921 sp<IGraphicBufferProducer> bufferProducer;
mspector@google.comda9ca912016-02-08 17:07:06 -0800922 MetadataBufferType type = kMetadataBufferTypeInvalid;
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800923 status_t err = createInputSurface(node, port_index, dataSpace, &bufferProducer, &type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800924
mspector@google.comda9ca912016-02-08 17:07:06 -0800925 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
926 android_errorWriteLog(0x534e4554, "26324358");
927 }
928
Lajos Molnar05421982015-05-15 20:39:14 -0700929 reply->writeInt32(type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800930 reply->writeInt32(err);
931
932 if (err == OK) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800933 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
Andy McFadden7cd58532013-02-19 07:28:30 -0800934 }
935
936 return NO_ERROR;
937 }
938
Chong Zhangd291c222015-04-30 18:15:52 -0700939 case CREATE_PERSISTENT_INPUT_SURFACE:
940 {
941 CHECK_OMX_INTERFACE(IOMX, data, reply);
942
943 sp<IGraphicBufferProducer> bufferProducer;
944 sp<IGraphicBufferConsumer> bufferConsumer;
945 status_t err = createPersistentInputSurface(
946 &bufferProducer, &bufferConsumer);
947
948 reply->writeInt32(err);
949
950 if (err == OK) {
951 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
952 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
953 }
954
955 return NO_ERROR;
956 }
957
Chong Zhang8f469e12015-05-13 10:21:33 -0700958 case SET_INPUT_SURFACE:
Chong Zhangd291c222015-04-30 18:15:52 -0700959 {
960 CHECK_OMX_INTERFACE(IOMX, data, reply);
961
962 node_id node = (node_id)data.readInt32();
963 OMX_U32 port_index = data.readInt32();
964
965 sp<IGraphicBufferConsumer> bufferConsumer =
966 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
967
Wei Jia56c95c92016-01-06 10:30:46 -0800968 MetadataBufferType type = kMetadataBufferTypeInvalid;
Chong Zhangd291c222015-04-30 18:15:52 -0700969
Wei Jia56c95c92016-01-06 10:30:46 -0800970 status_t err = INVALID_OPERATION;
971 if (bufferConsumer == NULL) {
972 ALOGE("b/26392700");
973 } else {
974 err = setInputSurface(node, port_index, bufferConsumer, &type);
mspector@google.comc3ed9d02016-02-18 19:52:08 -0800975
976 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
977 android_errorWriteLog(0x534e4554, "26324358");
978 }
Wei Jia56c95c92016-01-06 10:30:46 -0800979 }
Chong Zhangd291c222015-04-30 18:15:52 -0700980
Lajos Molnar05421982015-05-15 20:39:14 -0700981 reply->writeInt32(type);
Chong Zhangd291c222015-04-30 18:15:52 -0700982 reply->writeInt32(err);
983 return NO_ERROR;
984 }
985
Andy McFadden7cd58532013-02-19 07:28:30 -0800986 case SIGNAL_END_OF_INPUT_STREAM:
987 {
988 CHECK_OMX_INTERFACE(IOMX, data, reply);
989
Andy Hung609b8152014-05-02 11:05:04 -0700990 node_id node = (node_id)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800991
992 status_t err = signalEndOfInputStream(node);
993 reply->writeInt32(err);
994
995 return NO_ERROR;
996 }
997
James Donge8707722010-10-20 17:38:41 -0700998 case STORE_META_DATA_IN_BUFFERS:
999 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001000 CHECK_OMX_INTERFACE(IOMX, data, reply);
James Donge8707722010-10-20 17:38:41 -07001001
Andy Hung609b8152014-05-02 11:05:04 -07001002 node_id node = (node_id)data.readInt32();
James Donge8707722010-10-20 17:38:41 -07001003 OMX_U32 port_index = data.readInt32();
1004 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1005
mspector@google.comda9ca912016-02-08 17:07:06 -08001006 MetadataBufferType type = kMetadataBufferTypeInvalid;
Lajos Molnar05421982015-05-15 20:39:14 -07001007 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
mspector@google.comda9ca912016-02-08 17:07:06 -08001008
Lajos Molnar05421982015-05-15 20:39:14 -07001009 reply->writeInt32(type);
James Donge8707722010-10-20 17:38:41 -07001010 reply->writeInt32(err);
1011
1012 return NO_ERROR;
1013 }
1014
Lajos Molnar56ce7262013-05-02 16:30:48 -07001015 case PREPARE_FOR_ADAPTIVE_PLAYBACK:
1016 {
1017 CHECK_OMX_INTERFACE(IOMX, data, reply);
1018
Andy Hung609b8152014-05-02 11:05:04 -07001019 node_id node = (node_id)data.readInt32();
Lajos Molnar56ce7262013-05-02 16:30:48 -07001020 OMX_U32 port_index = data.readInt32();
1021 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1022 OMX_U32 max_width = data.readInt32();
1023 OMX_U32 max_height = data.readInt32();
1024
1025 status_t err = prepareForAdaptivePlayback(
1026 node, port_index, enable, max_width, max_height);
1027 reply->writeInt32(err);
1028
1029 return NO_ERROR;
1030 }
1031
Rachad5a446aa2014-07-29 16:47:56 -07001032 case CONFIGURE_VIDEO_TUNNEL_MODE:
1033 {
1034 CHECK_OMX_INTERFACE(IOMX, data, reply);
1035
1036 node_id node = (node_id)data.readInt32();
1037 OMX_U32 port_index = data.readInt32();
1038 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
1039 OMX_U32 audio_hw_sync = data.readInt32();
1040
Lajos Molnara63141a2016-02-11 16:40:36 -08001041 native_handle_t *sideband_handle = NULL;
Rachad5a446aa2014-07-29 16:47:56 -07001042 status_t err = configureVideoTunnelMode(
1043 node, port_index, tunneled, audio_hw_sync, &sideband_handle);
1044 reply->writeInt32(err);
mspector@google.com9d72eb02016-02-08 10:56:13 -08001045 if(err == OK){
1046 reply->writeNativeHandle(sideband_handle);
1047 }
Rachad5a446aa2014-07-29 16:47:56 -07001048
1049 return NO_ERROR;
1050 }
1051
Lajos Molnara63141a2016-02-11 16:40:36 -08001052 case ALLOC_SECURE_BUFFER:
Andreas Huber20111aa2009-07-14 16:56:47 -07001053 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001054 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001055
Andy Hung609b8152014-05-02 11:05:04 -07001056 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001057 OMX_U32 port_index = data.readInt32();
Wei Jia8dde7262015-09-28 11:32:23 -07001058 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
1059 ALOGE("b/24310423");
1060 reply->writeInt32(INVALID_OPERATION);
1061 return NO_ERROR;
1062 }
1063
Glenn Kastene03dd222014-01-28 11:04:39 -08001064 size_t size = data.readInt64();
Andreas Huber20111aa2009-07-14 16:56:47 -07001065
1066 buffer_id buffer;
Lajos Molnara63141a2016-02-11 16:40:36 -08001067 void *buffer_data = NULL;
Lajos Molnar1b40f282016-05-09 22:24:52 -07001068 sp<NativeHandle> native_handle;
Lajos Molnara63141a2016-02-11 16:40:36 -08001069 status_t err = allocateSecureBuffer(
1070 node, port_index, size, &buffer, &buffer_data, &native_handle);
Andreas Huber20111aa2009-07-14 16:56:47 -07001071 reply->writeInt32(err);
1072
1073 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001074 reply->writeInt32((int32_t)buffer);
1075 reply->writeInt64((uintptr_t)buffer_data);
Lajos Molnara63141a2016-02-11 16:40:36 -08001076 if (buffer_data == NULL) {
Lajos Molnar1b40f282016-05-09 22:24:52 -07001077 reply->writeNativeHandle(native_handle == NULL ? NULL : native_handle->handle());
Lajos Molnara63141a2016-02-11 16:40:36 -08001078 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001079 }
1080
1081 return NO_ERROR;
1082 }
1083
1084 case ALLOC_BUFFER_WITH_BACKUP:
1085 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001086 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001087
Andy Hung609b8152014-05-02 11:05:04 -07001088 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001089 OMX_U32 port_index = data.readInt32();
1090 sp<IMemory> params =
1091 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001092 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001093
Wei Jia56c95c92016-01-06 10:30:46 -08001094 if (params == NULL) {
1095 ALOGE("b/26392700");
1096 reply->writeInt32(INVALID_OPERATION);
1097 return NO_ERROR;
1098 }
1099
Andreas Huber20111aa2009-07-14 16:56:47 -07001100 buffer_id buffer;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001101 status_t err = allocateBufferWithBackup(
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001102 node, port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -07001103
1104 reply->writeInt32(err);
1105
1106 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001107 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -07001108 }
1109
1110 return NO_ERROR;
1111 }
1112
1113 case FREE_BUFFER:
1114 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001115 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001116
Andy Hung609b8152014-05-02 11:05:04 -07001117 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001118 OMX_U32 port_index = data.readInt32();
Andy Hung609b8152014-05-02 11:05:04 -07001119 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -07001120 reply->writeInt32(freeBuffer(node, port_index, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -07001121
1122 return NO_ERROR;
1123 }
1124
1125 case FILL_BUFFER:
1126 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001127 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001128
Andy Hung609b8152014-05-02 11:05:04 -07001129 node_id node = (node_id)data.readInt32();
1130 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001131 bool haveFence = data.readInt32();
1132 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1133 reply->writeInt32(fillBuffer(node, buffer, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001134
1135 return NO_ERROR;
1136 }
1137
1138 case EMPTY_BUFFER:
1139 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001140 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001141
Andy Hung609b8152014-05-02 11:05:04 -07001142 node_id node = (node_id)data.readInt32();
1143 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001144 OMX_U32 range_offset = data.readInt32();
1145 OMX_U32 range_length = data.readInt32();
1146 OMX_U32 flags = data.readInt32();
1147 OMX_TICKS timestamp = data.readInt64();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001148 bool haveFence = data.readInt32();
1149 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1150 reply->writeInt32(emptyBuffer(
1151 node, buffer, range_offset, range_length, flags, timestamp, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001152
1153 return NO_ERROR;
1154 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001155
Andreas Huber693d2712009-08-14 14:37:10 -07001156 case GET_EXTENSION_INDEX:
1157 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001158 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -07001159
Andy Hung609b8152014-05-02 11:05:04 -07001160 node_id node = (node_id)data.readInt32();
Andreas Huber693d2712009-08-14 14:37:10 -07001161 const char *parameter_name = data.readCString();
Andreas Huber7eaa9c92010-01-15 15:28:19 -08001162
Wei Jia56c95c92016-01-06 10:30:46 -08001163 if (parameter_name == NULL) {
1164 ALOGE("b/26392700");
1165 reply->writeInt32(INVALID_OPERATION);
1166 return NO_ERROR;
1167 }
1168
Andreas Huber693d2712009-08-14 14:37:10 -07001169 OMX_INDEXTYPE index;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001170 status_t err = getExtensionIndex(node, parameter_name, &index);
Andreas Huber693d2712009-08-14 14:37:10 -07001171
1172 reply->writeInt32(err);
1173
1174 if (err == OK) {
1175 reply->writeInt32(index);
1176 }
1177
1178 return OK;
1179 }
1180
Andreas Huber20111aa2009-07-14 16:56:47 -07001181 default:
1182 return BBinder::onTransact(code, data, reply, flags);
1183 }
1184}
1185
1186////////////////////////////////////////////////////////////////////////////////
1187
1188class BpOMXObserver : public BpInterface<IOMXObserver> {
1189public:
1190 BpOMXObserver(const sp<IBinder> &impl)
1191 : BpInterface<IOMXObserver>(impl) {
1192 }
1193
Lajos Molnar26a48f32015-06-04 10:30:02 -07001194 virtual void onMessages(const std::list<omx_message> &messages) {
Andreas Huber20111aa2009-07-14 16:56:47 -07001195 Parcel data, reply;
Lajos Molnar26a48f32015-06-04 10:30:02 -07001196 std::list<omx_message>::const_iterator it = messages.cbegin();
1197 bool first = true;
1198 while (it != messages.cend()) {
1199 const omx_message &msg = *it++;
1200 if (first) {
1201 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
1202 data.writeInt32(msg.node);
1203 first = false;
1204 }
1205 data.writeInt32(msg.fenceFd >= 0);
1206 if (msg.fenceFd >= 0) {
1207 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
1208 }
1209 data.writeInt32(msg.type);
1210 data.write(&msg.u, sizeof(msg.u));
1211 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
Lajos Molnar15ab4992015-06-01 10:54:31 -07001212 }
Lajos Molnar26a48f32015-06-04 10:30:02 -07001213 if (!first) {
1214 data.writeInt32(-1); // mark end
1215 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
1216 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001217 }
1218};
1219
1220IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
1221
1222status_t BnOMXObserver::onTransact(
1223 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
1224 switch (code) {
1225 case OBSERVER_ON_MSG:
1226 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001227 CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
Lajos Molnar26a48f32015-06-04 10:30:02 -07001228 IOMX::node_id node = data.readInt32();
1229 std::list<omx_message> messages;
1230 status_t err = FAILED_TRANSACTION; // must receive at least one message
1231 do {
1232 int haveFence = data.readInt32();
1233 if (haveFence < 0) { // we use -1 to mark end of messages
1234 break;
1235 }
1236 omx_message msg;
1237 msg.node = node;
1238 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1239 msg.type = (typeof(msg.type))data.readInt32();
1240 err = data.read(&msg.u, sizeof(msg.u));
1241 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
1242 messages.push_back(msg);
1243 } while (err == OK);
Andreas Huber20111aa2009-07-14 16:56:47 -07001244
Lajos Molnar26a48f32015-06-04 10:30:02 -07001245 if (err == OK) {
1246 onMessages(messages);
Lajos Molnar15ab4992015-06-01 10:54:31 -07001247 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001248
Lajos Molnar26a48f32015-06-04 10:30:02 -07001249 return err;
Andreas Huber20111aa2009-07-14 16:56:47 -07001250 }
1251
1252 default:
1253 return BBinder::onTransact(code, data, reply, flags);
1254 }
1255}
1256
Andreas Huber20111aa2009-07-14 16:56:47 -07001257} // namespace android