blob: e6b4347d537a0d82de44dff8ec0f3d93838279c4 [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(
316 node_id node, OMX_U32 port_index,
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);
323 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
324 if (err != OK) {
325 ALOGW("binder transaction failed: %d", err);
326 return err;
327 }
328
Lajos Molnar05421982015-05-15 20:39:14 -0700329 // read type even if createInputSurface failed
330 int negotiatedType = reply.readInt32();
331 if (type != NULL) {
332 *type = (MetadataBufferType)negotiatedType;
333 }
334
Andy McFadden7cd58532013-02-19 07:28:30 -0800335 err = reply.readInt32();
336 if (err != OK) {
337 return err;
338 }
339
340 *bufferProducer = IGraphicBufferProducer::asInterface(
341 reply.readStrongBinder());
342
343 return err;
344 }
345
Chong Zhangd291c222015-04-30 18:15:52 -0700346 virtual status_t createPersistentInputSurface(
347 sp<IGraphicBufferProducer> *bufferProducer,
348 sp<IGraphicBufferConsumer> *bufferConsumer) {
349 Parcel data, reply;
350 status_t err;
351 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
352 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply);
353 if (err != OK) {
354 ALOGW("binder transaction failed: %d", err);
355 return err;
356 }
357
358 err = reply.readInt32();
359 if (err != OK) {
360 return err;
361 }
362
363 *bufferProducer = IGraphicBufferProducer::asInterface(
364 reply.readStrongBinder());
365 *bufferConsumer = IGraphicBufferConsumer::asInterface(
366 reply.readStrongBinder());
367
368 return err;
369 }
370
Chong Zhang8f469e12015-05-13 10:21:33 -0700371 virtual status_t setInputSurface(
Chong Zhangd291c222015-04-30 18:15:52 -0700372 node_id node, OMX_U32 port_index,
Lajos Molnar05421982015-05-15 20:39:14 -0700373 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) {
Chong Zhangd291c222015-04-30 18:15:52 -0700374 Parcel data, reply;
375 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
376 status_t err;
377 data.writeInt32((int32_t)node);
378 data.writeInt32(port_index);
379 data.writeStrongBinder(IInterface::asBinder(bufferConsumer));
380
Chong Zhang8f469e12015-05-13 10:21:33 -0700381 err = remote()->transact(SET_INPUT_SURFACE, data, &reply);
Chong Zhangd291c222015-04-30 18:15:52 -0700382
383 if (err != OK) {
384 ALOGW("binder transaction failed: %d", err);
385 return err;
386 }
Lajos Molnar05421982015-05-15 20:39:14 -0700387
388 // read type even if setInputSurface failed
389 int negotiatedType = reply.readInt32();
390 if (type != NULL) {
391 *type = (MetadataBufferType)negotiatedType;
392 }
393
Chong Zhangd291c222015-04-30 18:15:52 -0700394 return reply.readInt32();
395 }
396
Andy McFadden7cd58532013-02-19 07:28:30 -0800397 virtual status_t signalEndOfInputStream(node_id node) {
398 Parcel data, reply;
399 status_t err;
400 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700401 data.writeInt32((int32_t)node);
Andy McFadden7cd58532013-02-19 07:28:30 -0800402 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply);
403 if (err != OK) {
404 ALOGW("binder transaction failed: %d", err);
405 return err;
406 }
407
408 return reply.readInt32();
409 }
410
James Donge8707722010-10-20 17:38:41 -0700411 virtual status_t storeMetaDataInBuffers(
Lajos Molnar05421982015-05-15 20:39:14 -0700412 node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
James Donge8707722010-10-20 17:38:41 -0700413 Parcel data, reply;
414 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700415 data.writeInt32((int32_t)node);
James Donge8707722010-10-20 17:38:41 -0700416 data.writeInt32(port_index);
417 data.writeInt32((uint32_t)enable);
418 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
419
Lajos Molnar05421982015-05-15 20:39:14 -0700420 // read type even storeMetaDataInBuffers failed
421 int negotiatedType = reply.readInt32();
422 if (type != NULL) {
423 *type = (MetadataBufferType)negotiatedType;
424 }
425
426 return reply.readInt32();
James Donge8707722010-10-20 17:38:41 -0700427 }
428
Lajos Molnar56ce7262013-05-02 16:30:48 -0700429 virtual status_t prepareForAdaptivePlayback(
430 node_id node, OMX_U32 port_index, OMX_BOOL enable,
431 OMX_U32 max_width, OMX_U32 max_height) {
432 Parcel data, reply;
433 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700434 data.writeInt32((int32_t)node);
Lajos Molnar56ce7262013-05-02 16:30:48 -0700435 data.writeInt32(port_index);
436 data.writeInt32((int32_t)enable);
437 data.writeInt32(max_width);
438 data.writeInt32(max_height);
439 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply);
440
441 status_t err = reply.readInt32();
442 return err;
443 }
444
Rachad5a446aa2014-07-29 16:47:56 -0700445 virtual status_t configureVideoTunnelMode(
446 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
447 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) {
448 Parcel data, reply;
449 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
450 data.writeInt32((int32_t)node);
451 data.writeInt32(portIndex);
452 data.writeInt32((int32_t)tunneled);
453 data.writeInt32(audioHwSync);
454 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply);
455
456 status_t err = reply.readInt32();
mspector@google.com9d72eb02016-02-08 10:56:13 -0800457 if (err == OK && sidebandHandle) {
Rachad5a446aa2014-07-29 16:47:56 -0700458 *sidebandHandle = (native_handle_t *)reply.readNativeHandle();
459 }
460 return err;
461 }
462
463
Lajos Molnara63141a2016-02-11 16:40:36 -0800464 virtual status_t allocateSecureBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700465 node_id node, OMX_U32 port_index, size_t size,
Lajos Molnara63141a2016-02-11 16:40:36 -0800466 buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700467 Parcel data, reply;
468 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700469 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700470 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800471 data.writeInt64(size);
Lajos Molnara63141a2016-02-11 16:40:36 -0800472 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700473
474 status_t err = reply.readInt32();
475 if (err != OK) {
476 *buffer = 0;
Lajos Molnara63141a2016-02-11 16:40:36 -0800477 *buffer_data = NULL;
478 *native_handle = NULL;
Andreas Huber20111aa2009-07-14 16:56:47 -0700479 return err;
480 }
481
Andy Hung609b8152014-05-02 11:05:04 -0700482 *buffer = (buffer_id)reply.readInt32();
483 *buffer_data = (void *)reply.readInt64();
Lajos Molnara63141a2016-02-11 16:40:36 -0800484 if (*buffer_data == NULL) {
485 *native_handle = reply.readNativeHandle();
486 } else {
487 *native_handle = NULL;
488 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700489 return err;
490 }
491
Andreas Huber318ad9c2009-10-15 13:46:54 -0700492 virtual status_t allocateBufferWithBackup(
Andreas Huber20111aa2009-07-14 16:56:47 -0700493 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700494 buffer_id *buffer, OMX_U32 allottedSize) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700495 Parcel data, reply;
496 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700497 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700498 data.writeInt32(port_index);
Marco Nelissen06b46062014-11-14 07:58:25 -0800499 data.writeStrongBinder(IInterface::asBinder(params));
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700500 data.writeInt32(allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700501 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
502
503 status_t err = reply.readInt32();
504 if (err != OK) {
505 *buffer = 0;
506
507 return err;
508 }
509
Andy Hung609b8152014-05-02 11:05:04 -0700510 *buffer = (buffer_id)reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700511
512 return err;
513 }
514
Andreas Huber318ad9c2009-10-15 13:46:54 -0700515 virtual status_t freeBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700516 node_id node, OMX_U32 port_index, buffer_id buffer) {
517 Parcel data, reply;
518 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700519 data.writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700520 data.writeInt32(port_index);
Andy Hung609b8152014-05-02 11:05:04 -0700521 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700522 remote()->transact(FREE_BUFFER, data, &reply);
523
524 return reply.readInt32();
525 }
526
Lajos Molnar15ab4992015-06-01 10:54:31 -0700527 virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700528 Parcel data, reply;
529 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700530 data.writeInt32((int32_t)node);
531 data.writeInt32((int32_t)buffer);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700532 data.writeInt32(fenceFd >= 0);
533 if (fenceFd >= 0) {
534 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
535 }
Andreas Huber36efa032009-10-08 11:02:27 -0700536 remote()->transact(FILL_BUFFER, data, &reply);
537
538 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700539 }
540
Andreas Huber318ad9c2009-10-15 13:46:54 -0700541 virtual status_t emptyBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700542 node_id node,
543 buffer_id buffer,
544 OMX_U32 range_offset, OMX_U32 range_length,
Lajos Molnar15ab4992015-06-01 10:54:31 -0700545 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700546 Parcel data, reply;
547 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700548 data.writeInt32((int32_t)node);
549 data.writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700550 data.writeInt32(range_offset);
551 data.writeInt32(range_length);
552 data.writeInt32(flags);
553 data.writeInt64(timestamp);
Lajos Molnar15ab4992015-06-01 10:54:31 -0700554 data.writeInt32(fenceFd >= 0);
555 if (fenceFd >= 0) {
556 data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
557 }
Andreas Huber36efa032009-10-08 11:02:27 -0700558 remote()->transact(EMPTY_BUFFER, data, &reply);
559
560 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700561 }
Andreas Huber8b938cd2009-07-31 11:52:50 -0700562
Andreas Huber318ad9c2009-10-15 13:46:54 -0700563 virtual status_t getExtensionIndex(
Andreas Huber693d2712009-08-14 14:37:10 -0700564 node_id node,
565 const char *parameter_name,
566 OMX_INDEXTYPE *index) {
567 Parcel data, reply;
568 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700569 data.writeInt32((int32_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700570 data.writeCString(parameter_name);
571
572 remote()->transact(GET_EXTENSION_INDEX, data, &reply);
573
574 status_t err = reply.readInt32();
575 if (err == OK) {
576 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
577 } else {
578 *index = OMX_IndexComponentStartUnused;
579 }
580
581 return err;
582 }
Andreas Hubere40cda72013-07-17 13:55:26 -0700583
584 virtual status_t setInternalOption(
585 node_id node,
586 OMX_U32 port_index,
587 InternalOptionType type,
588 const void *optionData,
589 size_t size) {
590 Parcel data, reply;
591 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andy Hung609b8152014-05-02 11:05:04 -0700592 data.writeInt32((int32_t)node);
Andreas Hubere40cda72013-07-17 13:55:26 -0700593 data.writeInt32(port_index);
Glenn Kastene03dd222014-01-28 11:04:39 -0800594 data.writeInt64(size);
Andreas Hubere40cda72013-07-17 13:55:26 -0700595 data.write(optionData, size);
596 data.writeInt32(type);
597 remote()->transact(SET_INTERNAL_OPTION, data, &reply);
598
599 return reply.readInt32();
600 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700601};
602
603IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
604
605////////////////////////////////////////////////////////////////////////////////
606
Andy McFadden7cd58532013-02-19 07:28:30 -0800607#define CHECK_OMX_INTERFACE(interface, data, reply) \
Andreas Huber20111aa2009-07-14 16:56:47 -0700608 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
Steve Block5ff1dd52012-01-05 23:22:43 +0000609 ALOGW("Call incorrectly routed to " #interface); \
Andreas Huber20111aa2009-07-14 16:56:47 -0700610 return PERMISSION_DENIED; \
611 } } while (0)
612
613status_t BnOMX::onTransact(
614 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
615 switch (code) {
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800616 case LIVES_LOCALLY:
617 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800618 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andy Hung609b8152014-05-02 11:05:04 -0700619 node_id node = (node_id)data.readInt32();
Andreas Huberd459b482012-01-31 11:16:24 -0800620 pid_t pid = (pid_t)data.readInt32();
621 reply->writeInt32(livesLocally(node, pid));
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800622
623 return OK;
624 }
625
Andreas Huber20111aa2009-07-14 16:56:47 -0700626 case LIST_NODES:
627 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800628 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700629
Andreas Huber134ee6a2009-12-16 09:30:55 -0800630 List<ComponentInfo> list;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700631 listNodes(&list);
Andreas Huber20111aa2009-07-14 16:56:47 -0700632
633 reply->writeInt32(list.size());
Andreas Huber134ee6a2009-12-16 09:30:55 -0800634 for (List<ComponentInfo>::iterator it = list.begin();
Andreas Huber20111aa2009-07-14 16:56:47 -0700635 it != list.end(); ++it) {
Andreas Huber134ee6a2009-12-16 09:30:55 -0800636 ComponentInfo &cur = *it;
637
638 reply->writeString8(cur.mName);
639 reply->writeInt32(cur.mRoles.size());
640 for (List<String8>::iterator role_it = cur.mRoles.begin();
641 role_it != cur.mRoles.end(); ++role_it) {
642 reply->writeString8(*role_it);
643 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700644 }
645
646 return NO_ERROR;
647 }
648
649 case ALLOCATE_NODE:
650 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800651 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700652
Andreas Huber318ad9c2009-10-15 13:46:54 -0700653 const char *name = data.readCString();
654
655 sp<IOMXObserver> observer =
656 interface_cast<IOMXObserver>(data.readStrongBinder());
657
Wei Jia56c95c92016-01-06 10:30:46 -0800658 if (name == NULL || observer == NULL) {
659 ALOGE("b/26392700");
660 reply->writeInt32(INVALID_OPERATION);
661 return NO_ERROR;
662 }
663
Andreas Huber20111aa2009-07-14 16:56:47 -0700664 node_id node;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700665
Marco Nelissen23858872016-02-17 13:12:13 -0800666 status_t err = allocateNode(name, observer,
667 NULL /* nodeBinder */, &node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700668 reply->writeInt32(err);
669 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700670 reply->writeInt32((int32_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700671 }
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800672
Andreas Huber20111aa2009-07-14 16:56:47 -0700673 return NO_ERROR;
674 }
675
676 case FREE_NODE:
677 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800678 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700679
Andy Hung609b8152014-05-02 11:05:04 -0700680 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700681
Andreas Huber318ad9c2009-10-15 13:46:54 -0700682 reply->writeInt32(freeNode(node));
Andreas Huber7eaa9c92010-01-15 15:28:19 -0800683
Andreas Huber20111aa2009-07-14 16:56:47 -0700684 return NO_ERROR;
685 }
686
687 case SEND_COMMAND:
688 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800689 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700690
Andy Hung609b8152014-05-02 11:05:04 -0700691 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700692
693 OMX_COMMANDTYPE cmd =
694 static_cast<OMX_COMMANDTYPE>(data.readInt32());
695
696 OMX_S32 param = data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -0700697 reply->writeInt32(sendCommand(node, cmd, param));
Andreas Huber20111aa2009-07-14 16:56:47 -0700698
699 return NO_ERROR;
700 }
701
702 case GET_PARAMETER:
Andreas Huber20111aa2009-07-14 16:56:47 -0700703 case SET_PARAMETER:
Andreas Huber693d2712009-08-14 14:37:10 -0700704 case GET_CONFIG:
Andreas Huber693d2712009-08-14 14:37:10 -0700705 case SET_CONFIG:
Andreas Hubere40cda72013-07-17 13:55:26 -0700706 case SET_INTERNAL_OPTION:
Andreas Huber693d2712009-08-14 14:37:10 -0700707 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800708 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -0700709
Andy Hung609b8152014-05-02 11:05:04 -0700710 node_id node = (node_id)data.readInt32();
Andreas Huber693d2712009-08-14 14:37:10 -0700711 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
712
Glenn Kastene03dd222014-01-28 11:04:39 -0800713 size_t size = data.readInt64();
Andreas Huber693d2712009-08-14 14:37:10 -0700714
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800715 status_t err = NOT_ENOUGH_DATA;
716 void *params = NULL;
717 size_t pageSize = 0;
718 size_t allocSize = 0;
719 if (code != SET_INTERNAL_OPTION && size < 8) {
720 // we expect the structure to contain at least the size and
721 // version, 8 bytes total
722 ALOGE("b/27207275 (%zu)", size);
723 android_errorWriteLog(0x534e4554, "27207275");
724 } else {
725 err = NO_MEMORY;
726 pageSize = (size_t) sysconf(_SC_PAGE_SIZE);
727 if (size > SIZE_MAX - (pageSize * 2)) {
728 ALOGE("requested param size too big");
Marco Nelissenf7a38822016-02-22 13:05:15 -0800729 } else {
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800730 allocSize = (size + pageSize * 2) & ~(pageSize - 1);
731 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE,
732 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */);
733 }
734 if (params != MAP_FAILED) {
735 err = data.read(params, size);
736 if (err != OK) {
737 android_errorWriteLog(0x534e4554, "26914474");
738 } else {
739 err = NOT_ENOUGH_DATA;
740 OMX_U32 declaredSize = *(OMX_U32*)params;
741 if (code != SET_INTERNAL_OPTION && declaredSize > size) {
742 // the buffer says it's bigger than it actually is
743 ALOGE("b/27207275 (%u/%zu)", declaredSize, size);
744 android_errorWriteLog(0x534e4554, "27207275");
745 } else {
746 // mark the last page as inaccessible, to avoid exploitation
747 // of codecs that access past the end of the allocation because
748 // they didn't check the size
749 mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE);
750 switch (code) {
751 case GET_PARAMETER:
752 err = getParameter(node, index, params, size);
753 break;
754 case SET_PARAMETER:
755 err = setParameter(node, index, params, size);
756 break;
757 case GET_CONFIG:
758 err = getConfig(node, index, params, size);
759 break;
760 case SET_CONFIG:
761 err = setConfig(node, index, params, size);
762 break;
763 case SET_INTERNAL_OPTION:
764 {
765 InternalOptionType type =
766 (InternalOptionType)data.readInt32();
Andreas Huberb3912902011-01-19 10:34:52 -0800767
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800768 err = setInternalOption(node, index, type, params, size);
769 break;
770 }
771
772 default:
773 TRESPASS();
774 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800775 }
Marco Nelissenf7a38822016-02-22 13:05:15 -0800776 }
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800777 } else {
778 ALOGE("couldn't map: %s", strerror(errno));
Andreas Hubere40cda72013-07-17 13:55:26 -0700779 }
Andreas Huberb3912902011-01-19 10:34:52 -0800780 }
781
782 reply->writeInt32(err);
783
784 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
785 reply->write(params, size);
786 }
787
Marco Nelissen2720c8b2016-02-29 12:47:20 -0800788 if (params) {
789 munmap(params, allocSize);
790 }
Andreas Huberb3912902011-01-19 10:34:52 -0800791 params = NULL;
Andreas Huber693d2712009-08-14 14:37:10 -0700792
793 return NO_ERROR;
794 }
795
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700796 case GET_STATE:
797 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800798 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700799
Andy Hung609b8152014-05-02 11:05:04 -0700800 node_id node = (node_id)data.readInt32();
Jamie Gennisb1d666f2011-10-19 21:14:13 -0700801 OMX_STATETYPE state = OMX_StateInvalid;
802
803 status_t err = getState(node, &state);
804 reply->writeInt32(state);
805 reply->writeInt32(err);
806
807 return NO_ERROR;
808 }
809
Lajos Molnara63141a2016-02-11 16:40:36 -0800810 case ENABLE_NATIVE_BUFFERS:
Jamie Gennis83750ea2010-08-30 16:48:38 -0700811 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800812 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700813
Andy Hung609b8152014-05-02 11:05:04 -0700814 node_id node = (node_id)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700815 OMX_U32 port_index = data.readInt32();
Lajos Molnara63141a2016-02-11 16:40:36 -0800816 OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700817 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
818
Lajos Molnara63141a2016-02-11 16:40:36 -0800819 status_t err = enableNativeBuffers(node, port_index, graphic, enable);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700820 reply->writeInt32(err);
821
822 return NO_ERROR;
823 }
824
Jamie Gennise2ce6452011-02-23 19:01:28 -0800825 case GET_GRAPHIC_BUFFER_USAGE:
826 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800827 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennise2ce6452011-02-23 19:01:28 -0800828
Andy Hung609b8152014-05-02 11:05:04 -0700829 node_id node = (node_id)data.readInt32();
Jamie Gennise2ce6452011-02-23 19:01:28 -0800830 OMX_U32 port_index = data.readInt32();
831
832 OMX_U32 usage = 0;
833 status_t err = getGraphicBufferUsage(node, port_index, &usage);
834 reply->writeInt32(err);
835 reply->writeInt32(usage);
836
837 return NO_ERROR;
838 }
839
Andreas Huber20111aa2009-07-14 16:56:47 -0700840 case USE_BUFFER:
841 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800842 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -0700843
Andy Hung609b8152014-05-02 11:05:04 -0700844 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700845 OMX_U32 port_index = data.readInt32();
846 sp<IMemory> params =
847 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700848 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700849
Wei Jia56c95c92016-01-06 10:30:46 -0800850 if (params == NULL) {
851 ALOGE("b/26392700");
852 reply->writeInt32(INVALID_OPERATION);
853 return NO_ERROR;
854 }
855
Andreas Huber20111aa2009-07-14 16:56:47 -0700856 buffer_id buffer;
Lajos Molnarcc7cc672015-06-01 14:58:37 -0700857 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700858 reply->writeInt32(err);
859
860 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700861 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700862 }
863
864 return NO_ERROR;
865 }
866
Jamie Gennis83750ea2010-08-30 16:48:38 -0700867 case USE_GRAPHIC_BUFFER:
868 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800869 CHECK_OMX_INTERFACE(IOMX, data, reply);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700870
Andy Hung609b8152014-05-02 11:05:04 -0700871 node_id node = (node_id)data.readInt32();
Jamie Gennis83750ea2010-08-30 16:48:38 -0700872 OMX_U32 port_index = data.readInt32();
873 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
874 data.read(*graphicBuffer);
875
876 buffer_id buffer;
877 status_t err = useGraphicBuffer(
878 node, port_index, graphicBuffer, &buffer);
879 reply->writeInt32(err);
880
881 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -0700882 reply->writeInt32((int32_t)buffer);
Jamie Gennis83750ea2010-08-30 16:48:38 -0700883 }
884
885 return NO_ERROR;
886 }
887
Lajos Molnard0715862013-07-22 12:57:43 -0700888 case UPDATE_GRAPHIC_BUFFER_IN_META:
889 {
890 CHECK_OMX_INTERFACE(IOMX, data, reply);
891
Andy Hung609b8152014-05-02 11:05:04 -0700892 node_id node = (node_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700893 OMX_U32 port_index = data.readInt32();
894 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
895 data.read(*graphicBuffer);
Andy Hung609b8152014-05-02 11:05:04 -0700896 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnard0715862013-07-22 12:57:43 -0700897
898 status_t err = updateGraphicBufferInMeta(
899 node, port_index, graphicBuffer, buffer);
900 reply->writeInt32(err);
901
902 return NO_ERROR;
903 }
904
Andy McFadden7cd58532013-02-19 07:28:30 -0800905 case CREATE_INPUT_SURFACE:
906 {
907 CHECK_OMX_INTERFACE(IOMX, data, reply);
908
Andy Hung609b8152014-05-02 11:05:04 -0700909 node_id node = (node_id)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800910 OMX_U32 port_index = data.readInt32();
911
912 sp<IGraphicBufferProducer> bufferProducer;
mspector@google.comda9ca912016-02-08 17:07:06 -0800913 MetadataBufferType type = kMetadataBufferTypeInvalid;
Lajos Molnar05421982015-05-15 20:39:14 -0700914 status_t err = createInputSurface(node, port_index, &bufferProducer, &type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800915
mspector@google.comda9ca912016-02-08 17:07:06 -0800916 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
917 android_errorWriteLog(0x534e4554, "26324358");
918 }
919
Lajos Molnar05421982015-05-15 20:39:14 -0700920 reply->writeInt32(type);
Andy McFadden7cd58532013-02-19 07:28:30 -0800921 reply->writeInt32(err);
922
923 if (err == OK) {
Marco Nelissen06b46062014-11-14 07:58:25 -0800924 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
Andy McFadden7cd58532013-02-19 07:28:30 -0800925 }
926
927 return NO_ERROR;
928 }
929
Chong Zhangd291c222015-04-30 18:15:52 -0700930 case CREATE_PERSISTENT_INPUT_SURFACE:
931 {
932 CHECK_OMX_INTERFACE(IOMX, data, reply);
933
934 sp<IGraphicBufferProducer> bufferProducer;
935 sp<IGraphicBufferConsumer> bufferConsumer;
936 status_t err = createPersistentInputSurface(
937 &bufferProducer, &bufferConsumer);
938
939 reply->writeInt32(err);
940
941 if (err == OK) {
942 reply->writeStrongBinder(IInterface::asBinder(bufferProducer));
943 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer));
944 }
945
946 return NO_ERROR;
947 }
948
Chong Zhang8f469e12015-05-13 10:21:33 -0700949 case SET_INPUT_SURFACE:
Chong Zhangd291c222015-04-30 18:15:52 -0700950 {
951 CHECK_OMX_INTERFACE(IOMX, data, reply);
952
953 node_id node = (node_id)data.readInt32();
954 OMX_U32 port_index = data.readInt32();
955
956 sp<IGraphicBufferConsumer> bufferConsumer =
957 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder());
958
Wei Jia56c95c92016-01-06 10:30:46 -0800959 MetadataBufferType type = kMetadataBufferTypeInvalid;
Chong Zhangd291c222015-04-30 18:15:52 -0700960
Wei Jia56c95c92016-01-06 10:30:46 -0800961 status_t err = INVALID_OPERATION;
962 if (bufferConsumer == NULL) {
963 ALOGE("b/26392700");
964 } else {
965 err = setInputSurface(node, port_index, bufferConsumer, &type);
mspector@google.comc3ed9d02016-02-18 19:52:08 -0800966
967 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) {
968 android_errorWriteLog(0x534e4554, "26324358");
969 }
Wei Jia56c95c92016-01-06 10:30:46 -0800970 }
Chong Zhangd291c222015-04-30 18:15:52 -0700971
Lajos Molnar05421982015-05-15 20:39:14 -0700972 reply->writeInt32(type);
Chong Zhangd291c222015-04-30 18:15:52 -0700973 reply->writeInt32(err);
974 return NO_ERROR;
975 }
976
Andy McFadden7cd58532013-02-19 07:28:30 -0800977 case SIGNAL_END_OF_INPUT_STREAM:
978 {
979 CHECK_OMX_INTERFACE(IOMX, data, reply);
980
Andy Hung609b8152014-05-02 11:05:04 -0700981 node_id node = (node_id)data.readInt32();
Andy McFadden7cd58532013-02-19 07:28:30 -0800982
983 status_t err = signalEndOfInputStream(node);
984 reply->writeInt32(err);
985
986 return NO_ERROR;
987 }
988
James Donge8707722010-10-20 17:38:41 -0700989 case STORE_META_DATA_IN_BUFFERS:
990 {
Andy McFadden7cd58532013-02-19 07:28:30 -0800991 CHECK_OMX_INTERFACE(IOMX, data, reply);
James Donge8707722010-10-20 17:38:41 -0700992
Andy Hung609b8152014-05-02 11:05:04 -0700993 node_id node = (node_id)data.readInt32();
James Donge8707722010-10-20 17:38:41 -0700994 OMX_U32 port_index = data.readInt32();
995 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
996
mspector@google.comda9ca912016-02-08 17:07:06 -0800997 MetadataBufferType type = kMetadataBufferTypeInvalid;
Lajos Molnar05421982015-05-15 20:39:14 -0700998 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
mspector@google.comda9ca912016-02-08 17:07:06 -0800999
Lajos Molnar05421982015-05-15 20:39:14 -07001000 reply->writeInt32(type);
James Donge8707722010-10-20 17:38:41 -07001001 reply->writeInt32(err);
1002
1003 return NO_ERROR;
1004 }
1005
Lajos Molnar56ce7262013-05-02 16:30:48 -07001006 case PREPARE_FOR_ADAPTIVE_PLAYBACK:
1007 {
1008 CHECK_OMX_INTERFACE(IOMX, data, reply);
1009
Andy Hung609b8152014-05-02 11:05:04 -07001010 node_id node = (node_id)data.readInt32();
Lajos Molnar56ce7262013-05-02 16:30:48 -07001011 OMX_U32 port_index = data.readInt32();
1012 OMX_BOOL enable = (OMX_BOOL)data.readInt32();
1013 OMX_U32 max_width = data.readInt32();
1014 OMX_U32 max_height = data.readInt32();
1015
1016 status_t err = prepareForAdaptivePlayback(
1017 node, port_index, enable, max_width, max_height);
1018 reply->writeInt32(err);
1019
1020 return NO_ERROR;
1021 }
1022
Rachad5a446aa2014-07-29 16:47:56 -07001023 case CONFIGURE_VIDEO_TUNNEL_MODE:
1024 {
1025 CHECK_OMX_INTERFACE(IOMX, data, reply);
1026
1027 node_id node = (node_id)data.readInt32();
1028 OMX_U32 port_index = data.readInt32();
1029 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
1030 OMX_U32 audio_hw_sync = data.readInt32();
1031
Lajos Molnara63141a2016-02-11 16:40:36 -08001032 native_handle_t *sideband_handle = NULL;
Rachad5a446aa2014-07-29 16:47:56 -07001033 status_t err = configureVideoTunnelMode(
1034 node, port_index, tunneled, audio_hw_sync, &sideband_handle);
1035 reply->writeInt32(err);
mspector@google.com9d72eb02016-02-08 10:56:13 -08001036 if(err == OK){
1037 reply->writeNativeHandle(sideband_handle);
1038 }
Rachad5a446aa2014-07-29 16:47:56 -07001039
1040 return NO_ERROR;
1041 }
1042
Lajos Molnara63141a2016-02-11 16:40:36 -08001043 case ALLOC_SECURE_BUFFER:
Andreas Huber20111aa2009-07-14 16:56:47 -07001044 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001045 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001046
Andy Hung609b8152014-05-02 11:05:04 -07001047 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001048 OMX_U32 port_index = data.readInt32();
Wei Jia8dde7262015-09-28 11:32:23 -07001049 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
1050 ALOGE("b/24310423");
1051 reply->writeInt32(INVALID_OPERATION);
1052 return NO_ERROR;
1053 }
1054
Glenn Kastene03dd222014-01-28 11:04:39 -08001055 size_t size = data.readInt64();
Andreas Huber20111aa2009-07-14 16:56:47 -07001056
1057 buffer_id buffer;
Lajos Molnara63141a2016-02-11 16:40:36 -08001058 void *buffer_data = NULL;
1059 native_handle_t *native_handle = NULL;
1060 status_t err = allocateSecureBuffer(
1061 node, port_index, size, &buffer, &buffer_data, &native_handle);
Andreas Huber20111aa2009-07-14 16:56:47 -07001062 reply->writeInt32(err);
1063
1064 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001065 reply->writeInt32((int32_t)buffer);
1066 reply->writeInt64((uintptr_t)buffer_data);
Lajos Molnara63141a2016-02-11 16:40:36 -08001067 if (buffer_data == NULL) {
1068 reply->writeNativeHandle(native_handle);
1069 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001070 }
1071
1072 return NO_ERROR;
1073 }
1074
1075 case ALLOC_BUFFER_WITH_BACKUP:
1076 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001077 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001078
Andy Hung609b8152014-05-02 11:05:04 -07001079 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001080 OMX_U32 port_index = data.readInt32();
1081 sp<IMemory> params =
1082 interface_cast<IMemory>(data.readStrongBinder());
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001083 OMX_U32 allottedSize = data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001084
Wei Jia56c95c92016-01-06 10:30:46 -08001085 if (params == NULL) {
1086 ALOGE("b/26392700");
1087 reply->writeInt32(INVALID_OPERATION);
1088 return NO_ERROR;
1089 }
1090
Andreas Huber20111aa2009-07-14 16:56:47 -07001091 buffer_id buffer;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001092 status_t err = allocateBufferWithBackup(
Lajos Molnarcc7cc672015-06-01 14:58:37 -07001093 node, port_index, params, &buffer, allottedSize);
Andreas Huber20111aa2009-07-14 16:56:47 -07001094
1095 reply->writeInt32(err);
1096
1097 if (err == OK) {
Andy Hung609b8152014-05-02 11:05:04 -07001098 reply->writeInt32((int32_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -07001099 }
1100
1101 return NO_ERROR;
1102 }
1103
1104 case FREE_BUFFER:
1105 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001106 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001107
Andy Hung609b8152014-05-02 11:05:04 -07001108 node_id node = (node_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001109 OMX_U32 port_index = data.readInt32();
Andy Hung609b8152014-05-02 11:05:04 -07001110 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -07001111 reply->writeInt32(freeBuffer(node, port_index, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -07001112
1113 return NO_ERROR;
1114 }
1115
1116 case FILL_BUFFER:
1117 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001118 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001119
Andy Hung609b8152014-05-02 11:05:04 -07001120 node_id node = (node_id)data.readInt32();
1121 buffer_id buffer = (buffer_id)data.readInt32();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001122 bool haveFence = data.readInt32();
1123 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1124 reply->writeInt32(fillBuffer(node, buffer, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001125
1126 return NO_ERROR;
1127 }
1128
1129 case EMPTY_BUFFER:
1130 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001131 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber20111aa2009-07-14 16:56:47 -07001132
Andy Hung609b8152014-05-02 11:05:04 -07001133 node_id node = (node_id)data.readInt32();
1134 buffer_id buffer = (buffer_id)data.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -07001135 OMX_U32 range_offset = data.readInt32();
1136 OMX_U32 range_length = data.readInt32();
1137 OMX_U32 flags = data.readInt32();
1138 OMX_TICKS timestamp = data.readInt64();
Lajos Molnar15ab4992015-06-01 10:54:31 -07001139 bool haveFence = data.readInt32();
1140 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1141 reply->writeInt32(emptyBuffer(
1142 node, buffer, range_offset, range_length, flags, timestamp, fenceFd));
Andreas Huber20111aa2009-07-14 16:56:47 -07001143
1144 return NO_ERROR;
1145 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001146
Andreas Huber693d2712009-08-14 14:37:10 -07001147 case GET_EXTENSION_INDEX:
1148 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001149 CHECK_OMX_INTERFACE(IOMX, data, reply);
Andreas Huber693d2712009-08-14 14:37:10 -07001150
Andy Hung609b8152014-05-02 11:05:04 -07001151 node_id node = (node_id)data.readInt32();
Andreas Huber693d2712009-08-14 14:37:10 -07001152 const char *parameter_name = data.readCString();
Andreas Huber7eaa9c92010-01-15 15:28:19 -08001153
Wei Jia56c95c92016-01-06 10:30:46 -08001154 if (parameter_name == NULL) {
1155 ALOGE("b/26392700");
1156 reply->writeInt32(INVALID_OPERATION);
1157 return NO_ERROR;
1158 }
1159
Andreas Huber693d2712009-08-14 14:37:10 -07001160 OMX_INDEXTYPE index;
Andreas Huber318ad9c2009-10-15 13:46:54 -07001161 status_t err = getExtensionIndex(node, parameter_name, &index);
Andreas Huber693d2712009-08-14 14:37:10 -07001162
1163 reply->writeInt32(err);
1164
1165 if (err == OK) {
1166 reply->writeInt32(index);
1167 }
1168
1169 return OK;
1170 }
1171
Andreas Huber20111aa2009-07-14 16:56:47 -07001172 default:
1173 return BBinder::onTransact(code, data, reply, flags);
1174 }
1175}
1176
1177////////////////////////////////////////////////////////////////////////////////
1178
1179class BpOMXObserver : public BpInterface<IOMXObserver> {
1180public:
1181 BpOMXObserver(const sp<IBinder> &impl)
1182 : BpInterface<IOMXObserver>(impl) {
1183 }
1184
Lajos Molnar26a48f32015-06-04 10:30:02 -07001185 virtual void onMessages(const std::list<omx_message> &messages) {
Andreas Huber20111aa2009-07-14 16:56:47 -07001186 Parcel data, reply;
Lajos Molnar26a48f32015-06-04 10:30:02 -07001187 std::list<omx_message>::const_iterator it = messages.cbegin();
1188 bool first = true;
1189 while (it != messages.cend()) {
1190 const omx_message &msg = *it++;
1191 if (first) {
1192 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
1193 data.writeInt32(msg.node);
1194 first = false;
1195 }
1196 data.writeInt32(msg.fenceFd >= 0);
1197 if (msg.fenceFd >= 0) {
1198 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */);
1199 }
1200 data.writeInt32(msg.type);
1201 data.write(&msg.u, sizeof(msg.u));
1202 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
Lajos Molnar15ab4992015-06-01 10:54:31 -07001203 }
Lajos Molnar26a48f32015-06-04 10:30:02 -07001204 if (!first) {
1205 data.writeInt32(-1); // mark end
1206 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
1207 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001208 }
1209};
1210
1211IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
1212
1213status_t BnOMXObserver::onTransact(
1214 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
1215 switch (code) {
1216 case OBSERVER_ON_MSG:
1217 {
Andy McFadden7cd58532013-02-19 07:28:30 -08001218 CHECK_OMX_INTERFACE(IOMXObserver, data, reply);
Lajos Molnar26a48f32015-06-04 10:30:02 -07001219 IOMX::node_id node = data.readInt32();
1220 std::list<omx_message> messages;
1221 status_t err = FAILED_TRANSACTION; // must receive at least one message
1222 do {
1223 int haveFence = data.readInt32();
1224 if (haveFence < 0) { // we use -1 to mark end of messages
1225 break;
1226 }
1227 omx_message msg;
1228 msg.node = node;
1229 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
1230 msg.type = (typeof(msg.type))data.readInt32();
1231 err = data.read(&msg.u, sizeof(msg.u));
1232 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
1233 messages.push_back(msg);
1234 } while (err == OK);
Andreas Huber20111aa2009-07-14 16:56:47 -07001235
Lajos Molnar26a48f32015-06-04 10:30:02 -07001236 if (err == OK) {
1237 onMessages(messages);
Lajos Molnar15ab4992015-06-01 10:54:31 -07001238 }
Andreas Huber20111aa2009-07-14 16:56:47 -07001239
Lajos Molnar26a48f32015-06-04 10:30:02 -07001240 return err;
Andreas Huber20111aa2009-07-14 16:56:47 -07001241 }
1242
1243 default:
1244 return BBinder::onTransact(code, data, reply, flags);
1245 }
1246}
1247
Andreas Huber20111aa2009-07-14 16:56:47 -07001248} // namespace android