blob: 1ac098c5961a43523a48230ee018c9fb0beb8323 [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>
Andreas Huber20111aa2009-07-14 16:56:47 -070027
28namespace android {
29
30enum {
31 CONNECT = IBinder::FIRST_CALL_TRANSACTION,
Andreas Huber7eaa9c92010-01-15 15:28:19 -080032 LIVES_LOCALLY,
Andreas Huber20111aa2009-07-14 16:56:47 -070033 LIST_NODES,
34 ALLOCATE_NODE,
35 FREE_NODE,
36 SEND_COMMAND,
37 GET_PARAMETER,
38 SET_PARAMETER,
Andreas Huber693d2712009-08-14 14:37:10 -070039 GET_CONFIG,
40 SET_CONFIG,
Jamie Gennisb1d666f2011-10-19 21:14:13 -070041 GET_STATE,
Lajos Molnara63141a2016-02-11 16:40:36 -080042 ENABLE_NATIVE_BUFFERS,
Andreas Huber20111aa2009-07-14 16:56:47 -070043 USE_BUFFER,
Jamie Gennis83750ea2010-08-30 16:48:38 -070044 USE_GRAPHIC_BUFFER,
Andy McFadden7cd58532013-02-19 07:28:30 -080045 CREATE_INPUT_SURFACE,
Chong Zhangd291c222015-04-30 18:15:52 -070046 CREATE_PERSISTENT_INPUT_SURFACE,
Chong Zhang8f469e12015-05-13 10:21:33 -070047 SET_INPUT_SURFACE,
Andy McFadden7cd58532013-02-19 07:28:30 -080048 SIGNAL_END_OF_INPUT_STREAM,
James Donge8707722010-10-20 17:38:41 -070049 STORE_META_DATA_IN_BUFFERS,
Lajos Molnar56ce7262013-05-02 16:30:48 -070050 PREPARE_FOR_ADAPTIVE_PLAYBACK,
Lajos Molnara63141a2016-02-11 16:40:36 -080051 ALLOC_SECURE_BUFFER,
Andreas Huber20111aa2009-07-14 16:56:47 -070052 ALLOC_BUFFER_WITH_BACKUP,
53 FREE_BUFFER,
Andreas Huber20111aa2009-07-14 16:56:47 -070054 FILL_BUFFER,
55 EMPTY_BUFFER,
Andreas Huber693d2712009-08-14 14:37:10 -070056 GET_EXTENSION_INDEX,
Andreas Huber20111aa2009-07-14 16:56:47 -070057 OBSERVER_ON_MSG,
Jamie Gennise2ce6452011-02-23 19:01:28 -080058 GET_GRAPHIC_BUFFER_USAGE,
Andreas Hubere40cda72013-07-17 13:55:26 -070059 SET_INTERNAL_OPTION,
Lajos Molnard0715862013-07-22 12:57:43 -070060 UPDATE_GRAPHIC_BUFFER_IN_META,
Rachad5a446aa2014-07-29 16:47:56 -070061 CONFIGURE_VIDEO_TUNNEL_MODE,
Andreas Huber20111aa2009-07-14 16:56:47 -070062};
63
Andreas Huber20111aa2009-07-14 16:56:47 -070064class BpOMX : public BpInterface<IOMX> {
65public:
66 BpOMX(const sp<IBinder> &impl)
67 : BpInterface<IOMX>(impl) {
68 }
69
Andreas Huberd459b482012-01-31 11:16:24 -080070 virtual bool livesLocally(node_id node, pid_t pid) {
Andreas Huber7eaa9c92010-01-15 15:28:19 -080071 Parcel data, reply;
72 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -070073 data.writeInt32((int32_t)node);
Andreas Huber7eaa9c92010-01-15 15:28:19 -080074 data.writeInt32(pid);
75 remote()->transact(LIVES_LOCALLY, data, &reply);
76
77 return reply.readInt32() != 0;
78 }
79
Andreas Huber134ee6a2009-12-16 09:30:55 -080080 virtual status_t listNodes(List<ComponentInfo> *list) {
Andreas Huber20111aa2009-07-14 16:56:47 -070081 list->clear();
82
83 Parcel data, reply;
84 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
85 remote()->transact(LIST_NODES, data, &reply);
86
87 int32_t n = reply.readInt32();
88 for (int32_t i = 0; i < n; ++i) {
Andreas Huber134ee6a2009-12-16 09:30:55 -080089 list->push_back(ComponentInfo());
90 ComponentInfo &info = *--list->end();
Andreas Huber20111aa2009-07-14 16:56:47 -070091
Andreas Huber134ee6a2009-12-16 09:30:55 -080092 info.mName = reply.readString8();
93 int32_t numRoles = reply.readInt32();
94 for (int32_t j = 0; j < numRoles; ++j) {
95 info.mRoles.push_back(reply.readString8());
96 }
Andreas Huber20111aa2009-07-14 16:56:47 -070097 }
98
99 return OK;
100 }
101
Andreas Huber318ad9c2009-10-15 13:46:54 -0700102 virtual status_t allocateNode(
Marco Nelissen23858872016-02-17 13:12:13 -0800103 const char *name, const sp<IOMXObserver> &observer,
104 sp<IBinder> *nodeBinder,
105 node_id *node) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700106 Parcel data, reply;
107 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
108 data.writeCString(name);
Marco Nelissen06b46062014-11-14 07:58:25 -0800109 data.writeStrongBinder(IInterface::asBinder(observer));
Andreas Huber20111aa2009-07-14 16:56:47 -0700110 remote()->transact(ALLOCATE_NODE, data, &reply);
111
112 status_t err = reply.readInt32();
113 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700114 *node = (node_id)reply.readInt32();
Marco Nelissen23858872016-02-17 13:12:13 -0800115 if (nodeBinder != NULL) {
116 *nodeBinder = remote();
117 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700118 } else {
119 *node = 0;
120 }
121
122 return err;
123 }
124
Andreas Huber318ad9c2009-10-15 13:46:54 -0700125 virtual status_t freeNode(node_id node) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700126 Parcel data, reply;
127 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700128 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700129 remote()->transact(FREE_NODE, data, &reply);
130
131 return reply.readInt32();
132 }
133
Andreas Huber318ad9c2009-10-15 13:46:54 -0700134 virtual status_t sendCommand(
Andreas Huber20111aa2009-07-14 16:56:47 -0700135 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
136 Parcel data, reply;
137 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700138 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700139 data.writeInt32(cmd);
140 data.writeInt32(param);
141 remote()->transact(SEND_COMMAND, data, &reply);
142
143 return reply.readInt32();
144 }
145
Andreas Huber318ad9c2009-10-15 13:46:54 -0700146 virtual status_t getParameter(
Andreas Huber20111aa2009-07-14 16:56:47 -0700147 node_id node, OMX_INDEXTYPE index,
148 void *params, size_t size) {
149 Parcel data, reply;
150 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700151 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700152 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800153 data.writeInt64(size);
Andreas Huber20111aa2009-07-14 16:56:47 -0700154 data.write(params, size);
155 remote()->transact(GET_PARAMETER, data, &reply);
156
157 status_t err = reply.readInt32();
158 if (err != OK) {
159 return err;
160 }
161
162 reply.read(params, size);
163
164 return OK;
165 }
166
Andreas Huber318ad9c2009-10-15 13:46:54 -0700167 virtual status_t setParameter(
Andreas Huber20111aa2009-07-14 16:56:47 -0700168 node_id node, OMX_INDEXTYPE index,
169 const void *params, size_t size) {
170 Parcel data, reply;
171 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700172 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700173 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800174 data.writeInt64(size);
Andreas Huber20111aa2009-07-14 16:56:47 -0700175 data.write(params, size);
176 remote()->transact(SET_PARAMETER, data, &reply);
177
178 return reply.readInt32();
179 }
180
Andreas Huber318ad9c2009-10-15 13:46:54 -0700181 virtual status_t getConfig(
Andreas Huber693d2712009-08-14 14:37:10 -0700182 node_id node, OMX_INDEXTYPE index,
183 void *params, size_t size) {
184 Parcel data, reply;
185 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700186 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700187 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800188 data.writeInt64(size);
Andreas Huber693d2712009-08-14 14:37:10 -0700189 data.write(params, size);
190 remote()->transact(GET_CONFIG, data, &reply);
191
192 status_t err = reply.readInt32();
193 if (err != OK) {
194 return err;
195 }
196
197 reply.read(params, size);
198
199 return OK;
200 }
201
Andreas Huber318ad9c2009-10-15 13:46:54 -0700202 virtual status_t setConfig(
Andreas Huber693d2712009-08-14 14:37:10 -0700203 node_id node, OMX_INDEXTYPE index,
204 const void *params, size_t size) {
205 Parcel data, reply;
206 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700207 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700208 data.writeInt32(index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800209 data.writeInt64(size);
Andreas Huber693d2712009-08-14 14:37:10 -0700210 data.write(params, size);
211 remote()->transact(SET_CONFIG, data, &reply);
212
213 return reply.readInt32();
214 }
215
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700216 virtual status_t getState(
217 node_id node, OMX_STATETYPE* state) {
218 Parcel data, reply;
219 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700220 data.writeInt32((int32_t)node);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700221 remote()->transact(GET_STATE, data, &reply);
222
223 *state = static_cast<OMX_STATETYPE>(reply.readInt32());
224 return reply.readInt32();
225 }
226
Lajos Molnara63141a2016-02-11 16:40:36 -0800227 virtual status_t enableNativeBuffers(
228 node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
Jamie Gennis83750ea2010-08-30 16:48:38 -0700229 Parcel data, reply;
230 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700231 data.writeInt32((int32_t)node);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700232 data.writeInt32(port_index);
Lajos Molnara63141a2016-02-11 16:40:36 -0800233 data.writeInt32((uint32_t)graphic);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700234 data.writeInt32((uint32_t)enable);
Lajos Molnara63141a2016-02-11 16:40:36 -0800235 remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700236
237 status_t err = reply.readInt32();
238 return err;
239 }
240
Jamie Gennise2ce6452011-02-23 19:01:28 -0800241 virtual status_t getGraphicBufferUsage(
242 node_id node, OMX_U32 port_index, OMX_U32* usage) {
243 Parcel data, reply;
244 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700245 data.writeInt32((int32_t)node);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800246 data.writeInt32(port_index);
247 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
248
249 status_t err = reply.readInt32();
250 *usage = reply.readInt32();
251 return err;
252 }
253
Andreas Huber318ad9c2009-10-15 13:46:54 -0700254 virtual status_t useBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700255 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700256 buffer_id *buffer, OMX_U32 allottedSize) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700257 Parcel data, reply;
258 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700259 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700260 data.writeInt32(port_index);
Marco Nelissen06b46062014-11-14 07:58:25 -0800261 data.writeStrongBinder(IInterface::asBinder(params));
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700262 data.writeInt32(allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700263 remote()->transact(USE_BUFFER, data, &reply);
264
265 status_t err = reply.readInt32();
266 if (err != OK) {
267 *buffer = 0;
268
269 return err;
270 }
271
Andy Hung609b8152014-05-02 11:05:04 -0700272 *buffer = (buffer_id)reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700273
274 return err;
275 }
276
Jamie Gennis83750ea2010-08-30 16:48:38 -0700277
278 virtual status_t useGraphicBuffer(
279 node_id node, OMX_U32 port_index,
280 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
281 Parcel data, reply;
282 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700283 data.writeInt32((int32_t)node);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700284 data.writeInt32(port_index);
285 data.write(*graphicBuffer);
286 remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
287
288 status_t err = reply.readInt32();
289 if (err != OK) {
290 *buffer = 0;
291
292 return err;
293 }
294
Andy Hung609b8152014-05-02 11:05:04 -0700295 *buffer = (buffer_id)reply.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700296
297 return err;
298 }
299
Lajos Molnard0715862013-07-22 12:57:43 -0700300 virtual status_t updateGraphicBufferInMeta(
301 node_id node, OMX_U32 port_index,
302 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
303 Parcel data, reply;
304 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700305 data.writeInt32((int32_t)node);
Lajos Molnard0715862013-07-22 12:57:43 -0700306 data.writeInt32(port_index);
307 data.write(*graphicBuffer);
Andy Hung609b8152014-05-02 11:05:04 -0700308 data.writeInt32((int32_t)buffer);
Lajos Molnard0715862013-07-22 12:57:43 -0700309 remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
310
311 status_t err = reply.readInt32();
312 return err;
313 }
314
Andy McFadden7cd58532013-02-19 07:28:30 -0800315 virtual status_t createInputSurface(
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800316 node_id node, OMX_U32 port_index, android_dataspace dataSpace,
Lajos Molnar05421982015-05-15 20:39:14 -0700317 sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
Andy McFadden7cd58532013-02-19 07:28:30 -0800318 Parcel data, reply;
319 status_t err;
320 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700321 data.writeInt32((int32_t)node);
Andy McFadden7cd58532013-02-19 07:28:30 -0800322 data.writeInt32(port_index);
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800323 data.writeInt32(dataSpace);
Andy McFadden7cd58532013-02-19 07:28:30 -0800324 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
325 if (err != OK) {
326 ALOGW("binder transaction failed: %d", err);
327 return err;
328 }
329
Lajos Molnar05421982015-05-15 20:39:14 -0700330 // read type even if createInputSurface failed
331 int negotiatedType = reply.readInt32();
332 if (type != NULL) {
333 *type = (MetadataBufferType)negotiatedType;
334 }
335
Andy McFadden7cd58532013-02-19 07:28:30 -0800336 err = reply.readInt32();
337 if (err != OK) {
338 return err;
339 }
340
341 *bufferProducer = IGraphicBufferProducer::asInterface(
342 reply.readStrongBinder());
343
344 return err;
345 }
346
Chong Zhangd291c222015-04-30 18:15:52 -0700347 virtual status_t createPersistentInputSurface(
348 sp<IGraphicBufferProducer> *bufferProducer,
349 sp<IGraphicBufferConsumer> *bufferConsumer) {
350 Parcel data, reply;
351 status_t err;
352 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
353 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply);
354 if (err != OK) {
355 ALOGW("binder transaction failed: %d", err);
356 return err;
357 }
358
359 err = reply.readInt32();
360 if (err != OK) {
361 return err;
362 }
363
364 *bufferProducer = IGraphicBufferProducer::asInterface(
365 reply.readStrongBinder());
366 *bufferConsumer = IGraphicBufferConsumer::asInterface(
367 reply.readStrongBinder());
368
369 return err;
370 }
371
Chong Zhang8f469e12015-05-13 10:21:33 -0700372 virtual status_t setInputSurface(
Chong Zhangd291c222015-04-30 18:15:52 -0700373 node_id node, OMX_U32 port_index,
Lajos Molnar05421982015-05-15 20:39:14 -0700374 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) {
Chong Zhangd291c222015-04-30 18:15:52 -0700375 Parcel data, reply;
376 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
377 status_t err;
378 data.writeInt32((int32_t)node);
379 data.writeInt32(port_index);
380 data.writeStrongBinder(IInterface::asBinder(bufferConsumer));
381
Chong Zhang8f469e12015-05-13 10:21:33 -0700382 err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
Chong Zhangd291c222015-04-30 18:15:52 -0700383
384 if (err != OK) {
385 ALOGW("binder transaction failed: %d", err);
386 return err;
387 }
Lajos Molnar05421982015-05-15 20:39:14 -0700388
389 // read type even if setInputSurface failed
390 int negotiatedType = reply.readInt32();
391 if (type != NULL) {
392 *type = (MetadataBufferType)negotiatedType;
393 }
394
Chong Zhangd291c222015-04-30 18:15:52 -0700395 return reply.readInt32();
396 }
397
Andy McFadden7cd58532013-02-19 07:28:30 -0800398 virtual status_t signalEndOfInputStream(node_id node) {
399 Parcel data, reply;
400 status_t err;
401 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700402 data.writeInt32((int32_t)node);
Andy McFadden7cd58532013-02-19 07:28:30 -0800403 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply);
404 if (err != OK) {
405 ALOGW("binder transaction failed: %d", err);
406 return err;
407 }
408
409 return reply.readInt32();
410 }
411
James Donge8707722010-10-20 17:38:41 -0700412 virtual status_t storeMetaDataInBuffers(
Lajos Molnar05421982015-05-15 20:39:14 -0700413 node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
James Donge8707722010-10-20 17:38:41 -0700414 Parcel data, reply;
415 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700416 data.writeInt32((int32_t)node);
James Donge8707722010-10-20 17:38:41 -0700417 data.writeInt32(port_index);
418 data.writeInt32((uint32_t)enable);
419 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
420
Lajos Molnar05421982015-05-15 20:39:14 -0700421 // read type even storeMetaDataInBuffers failed
422 int negotiatedType = reply.readInt32();
423 if (type != NULL) {
424 *type = (MetadataBufferType)negotiatedType;
425 }
426
427 return reply.readInt32();
James Donge8707722010-10-20 17:38:41 -0700428 }
429
Lajos Molnar56ce7262013-05-02 16:30:48 -0700430 virtual status_t prepareForAdaptivePlayback(
431 node_id node, OMX_U32 port_index, OMX_BOOL enable,
432 OMX_U32 max_width, OMX_U32 max_height) {
433 Parcel data, reply;
434 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700435 data.writeInt32((int32_t)node);
Lajos Molnar56ce7262013-05-02 16:30:48 -0700436 data.writeInt32(port_index);
437 data.writeInt32((int32_t)enable);
438 data.writeInt32(max_width);
439 data.writeInt32(max_height);
440 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
441
442 status_t err = reply.readInt32();
443 return err;
444 }
445
Rachad5a446aa2014-07-29 16:47:56 -0700446 virtual status_t configureVideoTunnelMode(
447 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
448 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
449 Parcel data, reply;
450 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
451 data.writeInt32((int32_t)node);
452 data.writeInt32(portIndex);
453 data.writeInt32((int32_t)tunneled);
454 data.writeInt32(audioHwSync);
455 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
456
457 status_t err = reply.readInt32();
mspector@google.com9d72eb02016-02-08 10:56:13 -0800458 if (err == OK && sidebandHandle) {
Rachad5a446aa2014-07-29 16:47:56 -0700459 *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
460 }
461 return err;
462 }
463
464
Lajos Molnara63141a2016-02-11 16:40:36 -0800465 virtual status_t allocateSecureBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700466 node_id node, OMX_U32 port_index, size_t size,
Lajos Molnara63141a2016-02-11 16:40:36 -0800467 buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700468 Parcel data, reply;
469 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700470 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700471 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800472 data.writeInt64(size);
Lajos Molnara63141a2016-02-11 16:40:36 -0800473 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700474
475 status_t err = reply.readInt32();
476 if (err != OK) {
477 *buffer = 0;
Lajos Molnara63141a2016-02-11 16:40:36 -0800478 *buffer_data = NULL;
479 *native_handle = NULL;
Andreas Huber20111aa2009-07-14 16:56:47 -0700480 return err;
481 }
482
Andy Hung609b8152014-05-02 11:05:04 -0700483 *buffer = (buffer_id)reply.readInt32();
484 *buffer_data = (void *)reply.readInt64();
Lajos Molnara63141a2016-02-11 16:40:36 -0800485 if (*buffer_data == NULL) {
486 *native_handle = reply.readNativeHandle();
487 } else {
488 *native_handle = NULL;
489 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700490 return err;
491 }
492
Andreas Huber318ad9c2009-10-15 13:46:54 -0700493 virtual status_t allocateBufferWithBackup(
Andreas Huber20111aa2009-07-14 16:56:47 -0700494 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700495 buffer_id *buffer, OMX_U32 allottedSize) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700496 Parcel data, reply;
497 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700498 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700499 data.writeInt32(port_index);
Marco Nelissen06b46062014-11-14 07:58:25 -0800500 data.writeStrongBinder(IInterface::asBinder(params));
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700501 data.writeInt32(allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700502 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
503
504 status_t err = reply.readInt32();
505 if (err != OK) {
506 *buffer = 0;
507
508 return err;
509 }
510
Andy Hung609b8152014-05-02 11:05:04 -0700511 *buffer = (buffer_id)reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700512
513 return err;
514 }
515
Andreas Huber318ad9c2009-10-15 13:46:54 -0700516 virtual status_t freeBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700517 node_id node, OMX_U32 port_index, buffer_id buffer) {
518 Parcel data, reply;
519 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700520 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700521 data.writeInt32(port_index);
Andy Hung609b8152014-05-02 11:05:04 -0700522 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700523 remote()->transact(FREE_BUFFER, data, &reply);
524
525 return reply.readInt32();
526 }
527
Lajos Molnar15ab4992015-06-01 10:54:31 -0700528 virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700529 Parcel data, reply;
530 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700531 data.writeInt32((int32_t)node);
532 data.writeInt32((int32_t)buffer);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700533 data.writeInt32(fenceFd >= 0);
534 if (fenceFd >= 0) {
535 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
536 }
Andreas Huber36efa032009-10-08 11:02:27 -0700537 remote()->transact(FILL_BUFFER, data, &reply);
538
539 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700540 }
541
Andreas Huber318ad9c2009-10-15 13:46:54 -0700542 virtual status_t emptyBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700543 node_id node,
544 buffer_id buffer,
545 OMX_U32 range_offset, OMX_U32 range_length,
Lajos Molnar15ab4992015-06-01 10:54:31 -0700546 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700547 Parcel data, reply;
548 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700549 data.writeInt32((int32_t)node);
550 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700551 data.writeInt32(range_offset);
552 data.writeInt32(range_length);
553 data.writeInt32(flags);
554 data.writeInt64(timestamp);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700555 data.writeInt32(fenceFd >= 0);
556 if (fenceFd >= 0) {
557 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
558 }
Andreas Huber36efa032009-10-08 11:02:27 -0700559 remote()->transact(EMPTY_BUFFER, data, &reply);
560
561 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700562 }
Andreas Huber8b938cd2009-07-31 11:52:50 -0700563
Andreas Huber318ad9c2009-10-15 13:46:54 -0700564 virtual status_t getExtensionIndex(
Andreas Huber693d2712009-08-14 14:37:10 -0700565 node_id node,
566 const char *parameter_name,
567 OMX_INDEXTYPE *index) {
568 Parcel data, reply;
569 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700570 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700571 data.writeCString(parameter_name);
572
573 remote()->transact(GET_EXTENSION_INDEX, data, &reply);
574
575 status_t err = reply.readInt32();
576 if (err == OK) {
577 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
578 } else {
579 *index = OMX_IndexComponentStartUnused;
580 }
581
582 return err;
583 }
Andreas Hubere40cda72013-07-17 13:55:26 -0700584
585 virtual status_t setInternalOption(
586 node_id node,
587 OMX_U32 port_index,
588 InternalOptionType type,
589 const void *optionData,
590 size_t size) {
591 Parcel data, reply;
592 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700593 data.writeInt32((int32_t)node);
Andreas Hubere40cda72013-07-17 13:55:26 -0700594 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800595 data.writeInt64(size);
Andreas Hubere40cda72013-07-17 13:55:26 -0700596 data.write(optionData, size);
597 data.writeInt32(type);
598 remote()->transact(SET_INTERNAL_OPTION, data, &reply);
599
600 return reply.readInt32();
601 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700602};
603
604IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
605
606////////////////////////////////////////////////////////////////////////////////
607
Andy McFadden7cd58532013-02-19 07:28:30 -0800608#define CHECK_OMX_INTERFACE(interface, data, reply) \
Andreas Huber20111aa2009-07-14 16:56:47 -0700609 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
Steve Block5ff1dd52012-01-05 23:22:43 +0000610 ALOGW("Call incorrectly routed to " #interface); \
Andreas Huber20111aa2009-07-14 16:56:47 -0700611 return PERMISSION_DENIED; \
612 } } while (0)
613
614status_t BnOMX::onTransact(
615 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
616 switch (code) {
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800617 case LIVES_LOCALLY:
618 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800619 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andy Hung609b8152014-05-02 11:05:04 -0700620 node_id node = (node_id)data.readInt32();
Andreas Huberd459b482012-01-31 11:16:24 -0800621 pid_t pid = (pid_t)data.readInt32();
622 reply->writeInt32(livesLocally(node, pid));
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800623
624 return OK;
625 }
626
Andreas Huber20111aa2009-07-14 16:56:47 -0700627 case LIST_NODES:
628 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800629 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700630
Andreas Huber134ee6a2009-12-16 09:30:55 -0800631 List<ComponentInfo> list;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700632 listNodes(&list);
Andreas Huber20111aa2009-07-14 16:56:47 -0700633
634 reply->writeInt32(list.size());
Andreas Huber134ee6a2009-12-16 09:30:55 -0800635 for (List<ComponentInfo>::iterator it = list.begin();
Andreas Huber20111aa2009-07-14 16:56:47 -0700636 it != list.end(); ++it) {
Andreas Huber134ee6a2009-12-16 09:30:55 -0800637 ComponentInfo &cur = *it;
638
639 reply->writeString8(cur.mName);
640 reply->writeInt32(cur.mRoles.size());
641 for (List<String8>::iterator role_it = cur.mRoles.begin();
642 role_it != cur.mRoles.end(); ++role_it) {
643 reply->writeString8(*role_it);
644 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700645 }
646
647 return NO_ERROR;
648 }
649
650 case ALLOCATE_NODE:
651 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800652 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700653
Andreas Huber318ad9c2009-10-15 13:46:54 -0700654 const char *name = data.readCString();
655
656 sp<IOMXObserver> observer =
657 interface_cast<IOMXObserver>(data.readStrongBinder());
658
Wei Jia56c95c92016-01-06 10:30:46 -0800659 if (name == NULL || observer == NULL) {
660 ALOGE("b/26392700");
661 reply->writeInt32(INVALID_OPERATION);
662 return NO_ERROR;
663 }
664
Andreas Huber20111aa2009-07-14 16:56:47 -0700665 node_id node;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700666
Marco Nelissen23858872016-02-17 13:12:13 -0800667 status_t err = allocateNode(name, observer,
668 NULL /* nodeBinder */, &node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700669 reply->writeInt32(err);
670 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700671 reply->writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700672 }
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800673
Andreas Huber20111aa2009-07-14 16:56:47 -0700674 return NO_ERROR;
675 }
676
677 case FREE_NODE:
678 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800679 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700680
Andy Hung609b8152014-05-02 11:05:04 -0700681 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700682
Andreas Huber318ad9c2009-10-15 13:46:54 -0700683 reply->writeInt32(freeNode(node));
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800684
Andreas Huber20111aa2009-07-14 16:56:47 -0700685 return NO_ERROR;
686 }
687
688 case SEND_COMMAND:
689 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800690 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700691
Andy Hung609b8152014-05-02 11:05:04 -0700692 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700693
694 OMX_COMMANDTYPE cmd =
695 static_cast<OMX_COMMANDTYPE>(data.readInt32());
696
697 OMX_S32 param = data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -0700698 reply->writeInt32(sendCommand(node, cmd, param));
Andreas Huber20111aa2009-07-14 16:56:47 -0700699
700 return NO_ERROR;
701 }
702
703 case GET_PARAMETER:
Andreas Huber20111aa2009-07-14 16:56:47 -0700704 case SET_PARAMETER:
Andreas Huber693d2712009-08-14 14:37:10 -0700705 case GET_CONFIG:
Andreas Huber693d2712009-08-14 14:37:10 -0700706 case SET_CONFIG:
Andreas Hubere40cda72013-07-17 13:55:26 -0700707 case SET_INTERNAL_OPTION:
Andreas Huber693d2712009-08-14 14:37:10 -0700708 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800709 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -0700710
Andy Hung609b8152014-05-02 11:05:04 -0700711 node_id node = (node_id)data.readInt32();
Andreas Huber693d2712009-08-14 14:37:10 -0700712 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
713
Glenn Kastene03dd222014-01-28 11:04:39 -0800714 size_t size = data.readInt64();
Andreas Huber693d2712009-08-14 14:37:10 -0700715
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800716 status_t err = NOT_ENOUGH_DATA;
717 void *params = NULL;
718 size_t pageSize = 0;
719 size_t allocSize = 0;
720 if (code != SET_INTERNAL_OPTION && size < 8) {
721 // we expect the structure to contain at least the size and
722 // version, 8 bytes total
723 ALOGE("b/27207275 (%zu)", size);
724 android_errorWriteLog(0x534e4554, "27207275");
725 } else {
726 err = NO_MEMORY;
727 pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
728 if (size > SIZE_MAX - (pageSize * 2)) {
729 ALOGE("requested param size too big");
Marco Nelissenf7a38822016-02-22 13:05:15 -0800730 } else {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800731 allocSize = (size + pageSize * 2) & ~(pageSize - 1);
732 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
733 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
734 }
735 if (params != MAP_FAILED) {
736 err = data.read(params, size);
737 if (err != OK) {
738 android_errorWriteLog(0x534e4554, "26914474");
739 } else {
740 err = NOT_ENOUGH_DATA;
741 OMX_U32 declaredSize = *(OMX_U32*)params;
742 if (code != SET_INTERNAL_OPTION && declaredSize > size) {
743 // the buffer says it's bigger than it actually is
744 ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
745 android_errorWriteLog(0x534e4554, "27207275");
746 } else {
747 // mark the last page as inaccessible, to avoid exploitation
748 // of codecs that access past the end of the allocation because
749 // they didn't check the size
750 mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE);
751 switch (code) {
752 case GET_PARAMETER:
753 err = getParameter(node, index, params, size);
754 break;
755 case SET_PARAMETER:
756 err = setParameter(node, index, params, size);
757 break;
758 case GET_CONFIG:
759 err = getConfig(node, index, params, size);
760 break;
761 case SET_CONFIG:
762 err = setConfig(node, index, params, size);
763 break;
764 case SET_INTERNAL_OPTION:
765 {
766 InternalOptionType type =
767 (InternalOptionType)data.readInt32();
Andreas Huberb3912902011-01-19 10:34:52 -0800768
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800769 err = setInternalOption(node, index, type, params, size);
770 break;
771 }
772
773 default:
774 TRESPASS();
775 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800776 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800777 }
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800778 } else {
779 ALOGE("couldn't map: %s", strerror(errno));
Andreas Hubere40cda72013-07-17 13:55:26 -0700780 }
Andreas Huberb3912902011-01-19 10:34:52 -0800781 }
782
783 reply->writeInt32(err);
784
785 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
786 reply->write(params, size);
787 }
788
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800789 if (params) {
790 munmap(params, allocSize);
791 }
Andreas Huberb3912902011-01-19 10:34:52 -0800792 params = NULL;
Andreas Huber693d2712009-08-14 14:37:10 -0700793
794 return NO_ERROR;
795 }
796
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700797 case GET_STATE:
798 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800799 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700800
Andy Hung609b8152014-05-02 11:05:04 -0700801 node_id node = (node_id)data.readInt32();
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700802 OMX_STATETYPE state = OMX_StateInvalid;
803
804 status_t err = getState(node, &state);
805 reply->writeInt32(state);
806 reply->writeInt32(err);
807
808 return NO_ERROR;
809 }
810
Lajos Molnara63141a2016-02-11 16:40:36 -0800811 case ENABLE_NATIVE_BUFFERS:
Jamie Gennis83750ea2010-08-30 16:48:38 -0700812 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800813 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700814
Andy Hung609b8152014-05-02 11:05:04 -0700815 node_id node = (node_id)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700816 OMX_U32 port_index = data.readInt32();
Lajos Molnara63141a2016-02-11 16:40:36 -0800817 OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700818 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
819
Lajos Molnara63141a2016-02-11 16:40:36 -0800820 status_t err = enableNativeBuffers(node, port_index, graphic, enable);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700821 reply->writeInt32(err);
822
823 return NO_ERROR;
824 }
825
Jamie Gennise2ce6452011-02-23 19:01:28 -0800826 case GET_GRAPHIC_BUFFER_USAGE:
827 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800828 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800829
Andy Hung609b8152014-05-02 11:05:04 -0700830 node_id node = (node_id)data.readInt32();
Jamie Gennise2ce6452011-02-23 19:01:28 -0800831 OMX_U32 port_index = data.readInt32();
832
833 OMX_U32 usage = 0;
834 status_t err = getGraphicBufferUsage(node, port_index, &usage);
835 reply->writeInt32(err);
836 reply->writeInt32(usage);
837
838 return NO_ERROR;
839 }
840
Andreas Huber20111aa2009-07-14 16:56:47 -0700841 case USE_BUFFER:
842 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800843 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700844
Andy Hung609b8152014-05-02 11:05:04 -0700845 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700846 OMX_U32 port_index = data.readInt32();
847 sp<IMemory> params =
848 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700849 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700850
Wei Jia56c95c92016-01-06 10:30:46 -0800851 if (params == NULL) {
852 ALOGE("b/26392700");
853 reply->writeInt32(INVALID_OPERATION);
854 return NO_ERROR;
855 }
856
Andreas Huber20111aa2009-07-14 16:56:47 -0700857 buffer_id buffer;
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700858 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700859 reply->writeInt32(err);
860
861 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700862 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700863 }
864
865 return NO_ERROR;
866 }
867
Jamie Gennis83750ea2010-08-30 16:48:38 -0700868 case USE_GRAPHIC_BUFFER:
869 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800870 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700871
Andy Hung609b8152014-05-02 11:05:04 -0700872 node_id node = (node_id)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700873 OMX_U32 port_index = data.readInt32();
874 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
875 data.read(*graphicBuffer);
876
877 buffer_id buffer;
878 status_t err = useGraphicBuffer(
879 node, port_index, graphicBuffer, &buffer);
880 reply->writeInt32(err);
881
882 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700883 reply->writeInt32((int32_t)buffer);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700884 }
885
886 return NO_ERROR;
887 }
888
Lajos Molnard0715862013-07-22 12:57:43 -0700889 case UPDATE_GRAPHIC_BUFFER_IN_META:
890 {
891 CHECK_OMX_INTERFACE(IOMX, data, reply);
892
Andy Hung609b8152014-05-02 11:05:04 -0700893 node_id node = (node_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700894 OMX_U32 port_index = data.readInt32();
895 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
896 data.read(*graphicBuffer);
Andy Hung609b8152014-05-02 11:05:04 -0700897 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700898
899 status_t err = updateGraphicBufferInMeta(
900 node, port_index, graphicBuffer, buffer);
901 reply->writeInt32(err);
902
903 return NO_ERROR;
904 }
905
Andy McFadden7cd58532013-02-19 07:28:30 -0800906 case CREATE_INPUT_SURFACE:
907 {
908 CHECK_OMX_INTERFACE(IOMX, data, reply);
909
Andy Hung609b8152014-05-02 11:05:04 -0700910 node_id node = (node_id)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800911 OMX_U32 port_index = data.readInt32();
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800912 android_dataspace dataSpace = (android_dataspace)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800913
914 sp<IGraphicBufferProducer> bufferProducer;
mspector@google.comda9ca912016-02-08 17:07:06 -0800915 MetadataBufferType type = kMetadataBufferTypeInvalid;
Lajos Molnar57fad3c2016-03-08 13:09:35 -0800916 status_t err = createInputSurface(node, port_index, dataSpace, &bufferProducer, &type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800917
mspector@google.comda9ca912016-02-08 17:07:06 -0800918 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
919 android_errorWriteLog(0x534e4554, "26324358");
920 }
921
Lajos Molnar05421982015-05-15 20:39:14 -0700922 reply->writeInt32(type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800923 reply->writeInt32(err);
924
925 if (err == OK) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800926 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
Andy McFadden7cd58532013-02-19 07:28:30 -0800927 }
928
929 return NO_ERROR;
930 }
931
Chong Zhangd291c222015-04-30 18:15:52 -0700932 case CREATE_PERSISTENT_INPUT_SURFACE:
933 {
934 CHECK_OMX_INTERFACE(IOMX, data, reply);
935
936 sp<IGraphicBufferProducer> bufferProducer;
937 sp<IGraphicBufferConsumer> bufferConsumer;
938 status_t err = createPersistentInputSurface(
939 &bufferProducer, &bufferConsumer);
940
941 reply->writeInt32(err);
942
943 if (err == OK) {
944 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
945 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
946 }
947
948 return NO_ERROR;
949 }
950
Chong Zhang8f469e12015-05-13 10:21:33 -0700951 case SET_INPUT_SURFACE:
Chong Zhangd291c222015-04-30 18:15:52 -0700952 {
953 CHECK_OMX_INTERFACE(IOMX, data, reply);
954
955 node_id node = (node_id)data.readInt32();
956 OMX_U32 port_index = data.readInt32();
957
958 sp<IGraphicBufferConsumer> bufferConsumer =
959 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
960
Wei Jia56c95c92016-01-06 10:30:46 -0800961 MetadataBufferType type = kMetadataBufferTypeInvalid;
Chong Zhangd291c222015-04-30 18:15:52 -0700962
Wei Jia56c95c92016-01-06 10:30:46 -0800963 status_t err = INVALID_OPERATION;
964 if (bufferConsumer == NULL) {
965 ALOGE("b/26392700");
966 } else {
967 err = setInputSurface(node, port_index, bufferConsumer, &type);
mspector@google.comc3ed9d02016-02-18 19:52:08 -0800968
969 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
970 android_errorWriteLog(0x534e4554, "26324358");
971 }
Wei Jia56c95c92016-01-06 10:30:46 -0800972 }
Chong Zhangd291c222015-04-30 18:15:52 -0700973
Lajos Molnar05421982015-05-15 20:39:14 -0700974 reply->writeInt32(type);
Chong Zhangd291c222015-04-30 18:15:52 -0700975 reply->writeInt32(err);
976 return NO_ERROR;
977 }
978
Andy McFadden7cd58532013-02-19 07:28:30 -0800979 case SIGNAL_END_OF_INPUT_STREAM:
980 {
981 CHECK_OMX_INTERFACE(IOMX, data, reply);
982
Andy Hung609b8152014-05-02 11:05:04 -0700983 node_id node = (node_id)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800984
985 status_t err = signalEndOfInputStream(node);
986 reply->writeInt32(err);
987
988 return NO_ERROR;
989 }
990
James Donge8707722010-10-20 17:38:41 -0700991 case STORE_META_DATA_IN_BUFFERS:
992 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800993 CHECK_OMX_INTERFACE(IOMX, data, reply);
James Donge8707722010-10-20 17:38:41 -0700994
Andy Hung609b8152014-05-02 11:05:04 -0700995 node_id node = (node_id)data.readInt32();
James Donge8707722010-10-20 17:38:41 -0700996 OMX_U32 port_index = data.readInt32();
997 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
998
mspector@google.comda9ca912016-02-08 17:07:06 -0800999 MetadataBufferType type = kMetadataBufferTypeInvalid;
Lajos Molnar05421982015-05-15 20:39:14 -07001000 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
mspector@google.comda9ca912016-02-08 17:07:06 -08001001
Lajos Molnar05421982015-05-15 20:39:14 -07001002 reply->writeInt32(type);
James Donge8707722010-10-20 17:38:41 -07001003 reply->writeInt32(err);
1004
1005 return NO_ERROR;
1006 }
1007
Lajos Molnar56ce7262013-05-02 16:30:48 -07001008 case PREPARE_FOR_ADAPTIVE_PLAYBACK:
1009 {
1010 CHECK_OMX_INTERFACE(IOMX, data, reply);
1011
Andy Hung609b8152014-05-02 11:05:04 -07001012 node_id node = (node_id)data.readInt32();
Lajos Molnar56ce7262013-05-02 16:30:48 -07001013 OMX_U32 port_index = data.readInt32();
1014 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1015 OMX_U32 max_width = data.readInt32();
1016 OMX_U32 max_height = data.readInt32();
1017
1018 status_t err = prepareForAdaptivePlayback(
1019 node, port_index, enable, max_width, max_height);
1020 reply->writeInt32(err);
1021
1022 return NO_ERROR;
1023 }
1024
Rachad5a446aa2014-07-29 16:47:56 -07001025 case CONFIGURE_VIDEO_TUNNEL_MODE:
1026 {
1027 CHECK_OMX_INTERFACE(IOMX, data, reply);
1028
1029 node_id node = (node_id)data.readInt32();
1030 OMX_U32 port_index = data.readInt32();
1031 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
1032 OMX_U32 audio_hw_sync = data.readInt32();
1033
Lajos Molnara63141a2016-02-11 16:40:36 -08001034 native_handle_t *sideband_handle = NULL;
Rachad5a446aa2014-07-29 16:47:56 -07001035 status_t err = configureVideoTunnelMode(
1036 node, port_index, tunneled, audio_hw_sync, &sideband_handle);
1037 reply->writeInt32(err);
mspector@google.com9d72eb02016-02-08 10:56:13 -08001038 if(err == OK){
1039 reply->writeNativeHandle(sideband_handle);
1040 }
Rachad5a446aa2014-07-29 16:47:56 -07001041
1042 return NO_ERROR;
1043 }
1044
Lajos Molnara63141a2016-02-11 16:40:36 -08001045 case ALLOC_SECURE_BUFFER:
Andreas Huber20111aa2009-07-14 16:56:47 -07001046 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001047 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001048
Andy Hung609b8152014-05-02 11:05:04 -07001049 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001050 OMX_U32 port_index = data.readInt32();
Wei Jia8dde7262015-09-28 11:32:23 -07001051 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
1052 ALOGE("b/24310423");
1053 reply->writeInt32(INVALID_OPERATION);
1054 return NO_ERROR;
1055 }
1056
Glenn Kastene03dd222014-01-28 11:04:39 -08001057 size_t size = data.readInt64();
Andreas Huber20111aa2009-07-14 16:56:47 -07001058
1059 buffer_id buffer;
Lajos Molnara63141a2016-02-11 16:40:36 -08001060 void *buffer_data = NULL;
1061 native_handle_t *native_handle = NULL;
1062 status_t err = allocateSecureBuffer(
1063 node, port_index, size, &buffer, &buffer_data, &native_handle);
Andreas Huber20111aa2009-07-14 16:56:47 -07001064 reply->writeInt32(err);
1065
1066 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001067 reply->writeInt32((int32_t)buffer);
1068 reply->writeInt64((uintptr_t)buffer_data);
Lajos Molnara63141a2016-02-11 16:40:36 -08001069 if (buffer_data == NULL) {
1070 reply->writeNativeHandle(native_handle);
1071 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001072 }
1073
1074 return NO_ERROR;
1075 }
1076
1077 case ALLOC_BUFFER_WITH_BACKUP:
1078 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001079 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001080
Andy Hung609b8152014-05-02 11:05:04 -07001081 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001082 OMX_U32 port_index = data.readInt32();
1083 sp<IMemory> params =
1084 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001085 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001086
Wei Jia56c95c92016-01-06 10:30:46 -08001087 if (params == NULL) {
1088 ALOGE("b/26392700");
1089 reply->writeInt32(INVALID_OPERATION);
1090 return NO_ERROR;
1091 }
1092
Andreas Huber20111aa2009-07-14 16:56:47 -07001093 buffer_id buffer;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001094 status_t err = allocateBufferWithBackup(
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001095 node, port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -07001096
1097 reply->writeInt32(err);
1098
1099 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001100 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -07001101 }
1102
1103 return NO_ERROR;
1104 }
1105
1106 case FREE_BUFFER:
1107 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001108 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001109
Andy Hung609b8152014-05-02 11:05:04 -07001110 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001111 OMX_U32 port_index = data.readInt32();
Andy Hung609b8152014-05-02 11:05:04 -07001112 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -07001113 reply->writeInt32(freeBuffer(node, port_index, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -07001114
1115 return NO_ERROR;
1116 }
1117
1118 case FILL_BUFFER:
1119 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001120 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001121
Andy Hung609b8152014-05-02 11:05:04 -07001122 node_id node = (node_id)data.readInt32();
1123 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001124 bool haveFence = data.readInt32();
1125 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1126 reply->writeInt32(fillBuffer(node, buffer, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001127
1128 return NO_ERROR;
1129 }
1130
1131 case EMPTY_BUFFER:
1132 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001133 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001134
Andy Hung609b8152014-05-02 11:05:04 -07001135 node_id node = (node_id)data.readInt32();
1136 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001137 OMX_U32 range_offset = data.readInt32();
1138 OMX_U32 range_length = data.readInt32();
1139 OMX_U32 flags = data.readInt32();
1140 OMX_TICKS timestamp = data.readInt64();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001141 bool haveFence = data.readInt32();
1142 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1143 reply->writeInt32(emptyBuffer(
1144 node, buffer, range_offset, range_length, flags, timestamp, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001145
1146 return NO_ERROR;
1147 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001148
Andreas Huber693d2712009-08-14 14:37:10 -07001149 case GET_EXTENSION_INDEX:
1150 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001151 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -07001152
Andy Hung609b8152014-05-02 11:05:04 -07001153 node_id node = (node_id)data.readInt32();
Andreas Huber693d2712009-08-14 14:37:10 -07001154 const char *parameter_name = data.readCString();
Andreas Huber7eaa9c92010-01-15 15:28:19 -08001155
Wei Jia56c95c92016-01-06 10:30:46 -08001156 if (parameter_name == NULL) {
1157 ALOGE("b/26392700");
1158 reply->writeInt32(INVALID_OPERATION);
1159 return NO_ERROR;
1160 }
1161
Andreas Huber693d2712009-08-14 14:37:10 -07001162 OMX_INDEXTYPE index;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001163 status_t err = getExtensionIndex(node, parameter_name, &index);
Andreas Huber693d2712009-08-14 14:37:10 -07001164
1165 reply->writeInt32(err);
1166
1167 if (err == OK) {
1168 reply->writeInt32(index);
1169 }
1170
1171 return OK;
1172 }
1173
Andreas Huber20111aa2009-07-14 16:56:47 -07001174 default:
1175 return BBinder::onTransact(code, data, reply, flags);
1176 }
1177}
1178
1179////////////////////////////////////////////////////////////////////////////////
1180
1181class BpOMXObserver : public BpInterface<IOMXObserver> {
1182public:
1183 BpOMXObserver(const sp<IBinder> &impl)
1184 : BpInterface<IOMXObserver>(impl) {
1185 }
1186
Lajos Molnar26a48f32015-06-04 10:30:02 -07001187 virtual void onMessages(const std::list<omx_message> &messages) {
Andreas Huber20111aa2009-07-14 16:56:47 -07001188 Parcel data, reply;
Lajos Molnar26a48f32015-06-04 10:30:02 -07001189 std::list<omx_message>::const_iterator it = messages.cbegin();
1190 bool first = true;
1191 while (it != messages.cend()) {
1192 const omx_message &msg = *it++;
1193 if (first) {
1194 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
1195 data.writeInt32(msg.node);
1196 first = false;
1197 }
1198 data.writeInt32(msg.fenceFd >= 0);
1199 if (msg.fenceFd >= 0) {
1200 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
1201 }
1202 data.writeInt32(msg.type);
1203 data.write(&msg.u, sizeof(msg.u));
1204 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
Lajos Molnar15ab4992015-06-01 10:54:31 -07001205 }
Lajos Molnar26a48f32015-06-04 10:30:02 -07001206 if (!first) {
1207 data.writeInt32(-1); // mark end
1208 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
1209 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001210 }
1211};
1212
1213IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
1214
1215status_t BnOMXObserver::onTransact(
1216 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
1217 switch (code) {
1218 case OBSERVER_ON_MSG:
1219 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001220 CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
Lajos Molnar26a48f32015-06-04 10:30:02 -07001221 IOMX::node_id node = data.readInt32();
1222 std::list<omx_message> messages;
1223 status_t err = FAILED_TRANSACTION; // must receive at least one message
1224 do {
1225 int haveFence = data.readInt32();
1226 if (haveFence < 0) { // we use -1 to mark end of messages
1227 break;
1228 }
1229 omx_message msg;
1230 msg.node = node;
1231 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1232 msg.type = (typeof(msg.type))data.readInt32();
1233 err = data.read(&msg.u, sizeof(msg.u));
1234 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
1235 messages.push_back(msg);
1236 } while (err == OK);
Andreas Huber20111aa2009-07-14 16:56:47 -07001237
Lajos Molnar26a48f32015-06-04 10:30:02 -07001238 if (err == OK) {
1239 onMessages(messages);
Lajos Molnar15ab4992015-06-01 10:54:31 -07001240 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001241
Lajos Molnar26a48f32015-06-04 10:30:02 -07001242 return err;
Andreas Huber20111aa2009-07-14 16:56:47 -07001243 }
1244
1245 default:
1246 return BBinder::onTransact(code, data, reply, flags);
1247 }
1248}
1249
Andreas Huber20111aa2009-07-14 16:56:47 -07001250} // namespace android