blob: e74f1a95cb8ee019db6f4a733c1388dedf5331fa [file] [log] [blame]
Andreas Huber20111aa2009-07-14 16:56:47 -07001//#define LOG_NDEBUG 0
2#define LOG_TAG "IOMX"
3#include <utils/Log.h>
4
5#include <binder/IMemory.h>
6#include <binder/Parcel.h>
7#include <media/IOMX.h>
Andreas Huber8b938cd2009-07-31 11:52:50 -07008#include <ui/ISurface.h>
Andreas Huberf4148b52009-08-07 12:01:29 -07009#include <ui/Surface.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070010
11namespace android {
12
13enum {
14 CONNECT = IBinder::FIRST_CALL_TRANSACTION,
15 LIST_NODES,
16 ALLOCATE_NODE,
17 FREE_NODE,
18 SEND_COMMAND,
19 GET_PARAMETER,
20 SET_PARAMETER,
Andreas Huber693d2712009-08-14 14:37:10 -070021 GET_CONFIG,
22 SET_CONFIG,
Andreas Huber20111aa2009-07-14 16:56:47 -070023 USE_BUFFER,
24 ALLOC_BUFFER,
25 ALLOC_BUFFER_WITH_BACKUP,
26 FREE_BUFFER,
27 OBSERVE_NODE,
28 FILL_BUFFER,
29 EMPTY_BUFFER,
Andreas Huber693d2712009-08-14 14:37:10 -070030 GET_EXTENSION_INDEX,
Andreas Huber8b938cd2009-07-31 11:52:50 -070031 CREATE_RENDERER,
Andreas Huber20111aa2009-07-14 16:56:47 -070032 OBSERVER_ON_MSG,
Andreas Huber8b938cd2009-07-31 11:52:50 -070033 RENDERER_RENDER,
Andreas Huber20111aa2009-07-14 16:56:47 -070034};
35
Andreas Huberf4148b52009-08-07 12:01:29 -070036sp<IOMXRenderer> IOMX::createRenderer(
37 const sp<Surface> &surface,
38 const char *componentName,
39 OMX_COLOR_FORMATTYPE colorFormat,
40 size_t encodedWidth, size_t encodedHeight,
41 size_t displayWidth, size_t displayHeight) {
42 return createRenderer(
43 surface->getISurface(),
44 componentName, colorFormat, encodedWidth, encodedHeight,
45 displayWidth, displayHeight);
46}
47
Andreas Huber1b84df12009-09-15 12:49:11 -070048sp<IOMXRenderer> IOMX::createRendererFromJavaSurface(
49 JNIEnv *env, jobject javaSurface,
50 const char *componentName,
51 OMX_COLOR_FORMATTYPE colorFormat,
52 size_t encodedWidth, size_t encodedHeight,
53 size_t displayWidth, size_t displayHeight) {
54 jclass surfaceClass = env->FindClass("android/view/Surface");
55 if (surfaceClass == NULL) {
56 LOGE("Can't find android/view/Surface");
57 return NULL;
58 }
59
60 jfieldID surfaceID = env->GetFieldID(surfaceClass, "mSurface", "I");
61 if (surfaceID == NULL) {
62 LOGE("Can't find Surface.mSurface");
63 return NULL;
64 }
65
66 sp<Surface> surface = (Surface *)env->GetIntField(javaSurface, surfaceID);
67
68 return createRenderer(
69 surface, componentName, colorFormat, encodedWidth,
70 encodedHeight, displayWidth, displayHeight);
71}
72
Andreas Huber20111aa2009-07-14 16:56:47 -070073class BpOMX : public BpInterface<IOMX> {
74public:
75 BpOMX(const sp<IBinder> &impl)
76 : BpInterface<IOMX>(impl) {
77 }
78
Andreas Huber20111aa2009-07-14 16:56:47 -070079 virtual status_t list_nodes(List<String8> *list) {
80 list->clear();
81
82 Parcel data, reply;
83 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
84 remote()->transact(LIST_NODES, data, &reply);
85
86 int32_t n = reply.readInt32();
87 for (int32_t i = 0; i < n; ++i) {
88 String8 s = reply.readString8();
89
90 list->push_back(s);
91 }
92
93 return OK;
94 }
95
96 virtual status_t allocate_node(const char *name, node_id *node) {
97 Parcel data, reply;
98 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
99 data.writeCString(name);
100 remote()->transact(ALLOCATE_NODE, data, &reply);
101
102 status_t err = reply.readInt32();
103 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700104 *node = (void*)reply.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700105 } else {
106 *node = 0;
107 }
108
109 return err;
110 }
111
112 virtual status_t free_node(node_id node) {
113 Parcel data, reply;
114 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700115 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700116 remote()->transact(FREE_NODE, data, &reply);
117
118 return reply.readInt32();
119 }
120
121 virtual status_t send_command(
122 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
123 Parcel data, reply;
124 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700125 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700126 data.writeInt32(cmd);
127 data.writeInt32(param);
128 remote()->transact(SEND_COMMAND, data, &reply);
129
130 return reply.readInt32();
131 }
132
133 virtual status_t get_parameter(
134 node_id node, OMX_INDEXTYPE index,
135 void *params, size_t size) {
136 Parcel data, reply;
137 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700138 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700139 data.writeInt32(index);
140 data.writeInt32(size);
141 data.write(params, size);
142 remote()->transact(GET_PARAMETER, data, &reply);
143
144 status_t err = reply.readInt32();
145 if (err != OK) {
146 return err;
147 }
148
149 reply.read(params, size);
150
151 return OK;
152 }
153
154 virtual status_t set_parameter(
155 node_id node, OMX_INDEXTYPE index,
156 const void *params, size_t size) {
157 Parcel data, reply;
158 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700159 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700160 data.writeInt32(index);
161 data.writeInt32(size);
162 data.write(params, size);
163 remote()->transact(SET_PARAMETER, data, &reply);
164
165 return reply.readInt32();
166 }
167
Andreas Huber693d2712009-08-14 14:37:10 -0700168 virtual status_t get_config(
169 node_id node, OMX_INDEXTYPE index,
170 void *params, size_t size) {
171 Parcel data, reply;
172 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700173 data.writeIntPtr((intptr_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700174 data.writeInt32(index);
175 data.writeInt32(size);
176 data.write(params, size);
177 remote()->transact(GET_CONFIG, data, &reply);
178
179 status_t err = reply.readInt32();
180 if (err != OK) {
181 return err;
182 }
183
184 reply.read(params, size);
185
186 return OK;
187 }
188
189 virtual status_t set_config(
190 node_id node, OMX_INDEXTYPE index,
191 const void *params, size_t size) {
192 Parcel data, reply;
193 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700194 data.writeIntPtr((intptr_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700195 data.writeInt32(index);
196 data.writeInt32(size);
197 data.write(params, size);
198 remote()->transact(SET_CONFIG, data, &reply);
199
200 return reply.readInt32();
201 }
202
Andreas Huber20111aa2009-07-14 16:56:47 -0700203 virtual status_t use_buffer(
204 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
205 buffer_id *buffer) {
206 Parcel data, reply;
207 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700208 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700209 data.writeInt32(port_index);
210 data.writeStrongBinder(params->asBinder());
211 remote()->transact(USE_BUFFER, data, &reply);
212
213 status_t err = reply.readInt32();
214 if (err != OK) {
215 *buffer = 0;
216
217 return err;
218 }
219
Andreas Huberc6b59b72009-08-17 13:33:27 -0700220 *buffer = (void*)reply.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700221
222 return err;
223 }
224
225 virtual status_t allocate_buffer(
226 node_id node, OMX_U32 port_index, size_t size,
227 buffer_id *buffer) {
228 Parcel data, reply;
229 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700230 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700231 data.writeInt32(port_index);
232 data.writeInt32(size);
233 remote()->transact(ALLOC_BUFFER, data, &reply);
234
235 status_t err = reply.readInt32();
236 if (err != OK) {
237 *buffer = 0;
238
239 return err;
240 }
241
Andreas Huberc6b59b72009-08-17 13:33:27 -0700242 *buffer = (void*)reply.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700243
244 return err;
245 }
246
247 virtual status_t allocate_buffer_with_backup(
248 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
249 buffer_id *buffer) {
250 Parcel data, reply;
251 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700252 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700253 data.writeInt32(port_index);
254 data.writeStrongBinder(params->asBinder());
255 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
256
257 status_t err = reply.readInt32();
258 if (err != OK) {
259 *buffer = 0;
260
261 return err;
262 }
263
Andreas Huberc6b59b72009-08-17 13:33:27 -0700264 *buffer = (void*)reply.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700265
266 return err;
267 }
268
269 virtual status_t free_buffer(
270 node_id node, OMX_U32 port_index, buffer_id buffer) {
271 Parcel data, reply;
272 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700273 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700274 data.writeInt32(port_index);
Andreas Huberc6b59b72009-08-17 13:33:27 -0700275 data.writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700276 remote()->transact(FREE_BUFFER, data, &reply);
277
278 return reply.readInt32();
279 }
280
Andreas Huber20111aa2009-07-14 16:56:47 -0700281 virtual status_t observe_node(
282 node_id node, const sp<IOMXObserver> &observer) {
283 Parcel data, reply;
284 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700285 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700286 data.writeStrongBinder(observer->asBinder());
287 remote()->transact(OBSERVE_NODE, data, &reply);
288
289 return reply.readInt32();
290 }
291
Andreas Huber36efa032009-10-08 11:02:27 -0700292 virtual status_t fill_buffer(node_id node, buffer_id buffer) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700293 Parcel data, reply;
294 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700295 data.writeIntPtr((intptr_t)node);
296 data.writeIntPtr((intptr_t)buffer);
Andreas Huber36efa032009-10-08 11:02:27 -0700297 remote()->transact(FILL_BUFFER, data, &reply);
298
299 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700300 }
301
Andreas Huber36efa032009-10-08 11:02:27 -0700302 virtual status_t empty_buffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700303 node_id node,
304 buffer_id buffer,
305 OMX_U32 range_offset, OMX_U32 range_length,
306 OMX_U32 flags, OMX_TICKS timestamp) {
307 Parcel data, reply;
308 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700309 data.writeIntPtr((intptr_t)node);
310 data.writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700311 data.writeInt32(range_offset);
312 data.writeInt32(range_length);
313 data.writeInt32(flags);
314 data.writeInt64(timestamp);
Andreas Huber36efa032009-10-08 11:02:27 -0700315 remote()->transact(EMPTY_BUFFER, data, &reply);
316
317 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700318 }
Andreas Huber8b938cd2009-07-31 11:52:50 -0700319
Andreas Huber693d2712009-08-14 14:37:10 -0700320 virtual status_t get_extension_index(
321 node_id node,
322 const char *parameter_name,
323 OMX_INDEXTYPE *index) {
324 Parcel data, reply;
325 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700326 data.writeIntPtr((intptr_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700327 data.writeCString(parameter_name);
328
329 remote()->transact(GET_EXTENSION_INDEX, data, &reply);
330
331 status_t err = reply.readInt32();
332 if (err == OK) {
333 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
334 } else {
335 *index = OMX_IndexComponentStartUnused;
336 }
337
338 return err;
339 }
340
Andreas Huber8b938cd2009-07-31 11:52:50 -0700341 virtual sp<IOMXRenderer> createRenderer(
342 const sp<ISurface> &surface,
343 const char *componentName,
344 OMX_COLOR_FORMATTYPE colorFormat,
345 size_t encodedWidth, size_t encodedHeight,
346 size_t displayWidth, size_t displayHeight) {
347 Parcel data, reply;
348 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
349
350 data.writeStrongBinder(surface->asBinder());
351 data.writeCString(componentName);
352 data.writeInt32(colorFormat);
353 data.writeInt32(encodedWidth);
354 data.writeInt32(encodedHeight);
355 data.writeInt32(displayWidth);
356 data.writeInt32(displayHeight);
357
358 remote()->transact(CREATE_RENDERER, data, &reply);
359
360 return interface_cast<IOMXRenderer>(reply.readStrongBinder());
361 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700362};
363
364IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
365
366////////////////////////////////////////////////////////////////////////////////
367
368#define CHECK_INTERFACE(interface, data, reply) \
369 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
370 LOGW("Call incorrectly routed to " #interface); \
371 return PERMISSION_DENIED; \
372 } } while (0)
373
374status_t BnOMX::onTransact(
375 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
376 switch (code) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700377 case LIST_NODES:
378 {
379 CHECK_INTERFACE(IOMX, data, reply);
380
381 List<String8> list;
382 list_nodes(&list);
383
384 reply->writeInt32(list.size());
385 for (List<String8>::iterator it = list.begin();
386 it != list.end(); ++it) {
387 reply->writeString8(*it);
388 }
389
390 return NO_ERROR;
391 }
392
393 case ALLOCATE_NODE:
394 {
395 CHECK_INTERFACE(IOMX, data, reply);
396
397 node_id node;
398 status_t err = allocate_node(data.readCString(), &node);
399 reply->writeInt32(err);
400 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700401 reply->writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700402 }
403
404 return NO_ERROR;
405 }
406
407 case FREE_NODE:
408 {
409 CHECK_INTERFACE(IOMX, data, reply);
410
Andreas Huberc6b59b72009-08-17 13:33:27 -0700411 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700412
413 reply->writeInt32(free_node(node));
414
415 return NO_ERROR;
416 }
417
418 case SEND_COMMAND:
419 {
420 CHECK_INTERFACE(IOMX, data, reply);
421
Andreas Huberc6b59b72009-08-17 13:33:27 -0700422 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700423
424 OMX_COMMANDTYPE cmd =
425 static_cast<OMX_COMMANDTYPE>(data.readInt32());
426
427 OMX_S32 param = data.readInt32();
428 reply->writeInt32(send_command(node, cmd, param));
429
430 return NO_ERROR;
431 }
432
433 case GET_PARAMETER:
434 {
435 CHECK_INTERFACE(IOMX, data, reply);
436
Andreas Huberc6b59b72009-08-17 13:33:27 -0700437 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700438 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
439
440 size_t size = data.readInt32();
441
442 // XXX I am not happy with this but Parcel::readInplace didn't work.
443 void *params = malloc(size);
444 data.read(params, size);
445
446 status_t err = get_parameter(node, index, params, size);
447
448 reply->writeInt32(err);
449
450 if (err == OK) {
451 reply->write(params, size);
452 }
453
454 free(params);
455 params = NULL;
456
457 return NO_ERROR;
458 }
459
460 case SET_PARAMETER:
461 {
462 CHECK_INTERFACE(IOMX, data, reply);
463
Andreas Huberc6b59b72009-08-17 13:33:27 -0700464 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700465 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
466
467 size_t size = data.readInt32();
468 void *params = const_cast<void *>(data.readInplace(size));
469
470 reply->writeInt32(set_parameter(node, index, params, size));
471
472 return NO_ERROR;
473 }
474
Andreas Huber693d2712009-08-14 14:37:10 -0700475 case GET_CONFIG:
476 {
477 CHECK_INTERFACE(IOMX, data, reply);
478
Andreas Huberc6b59b72009-08-17 13:33:27 -0700479 node_id node = (void*)data.readIntPtr();
Andreas Huber693d2712009-08-14 14:37:10 -0700480 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
481
482 size_t size = data.readInt32();
483
484 // XXX I am not happy with this but Parcel::readInplace didn't work.
485 void *params = malloc(size);
486 data.read(params, size);
487
488 status_t err = get_config(node, index, params, size);
489
490 reply->writeInt32(err);
491
492 if (err == OK) {
493 reply->write(params, size);
494 }
495
496 free(params);
497 params = NULL;
498
499 return NO_ERROR;
500 }
501
502 case SET_CONFIG:
503 {
504 CHECK_INTERFACE(IOMX, data, reply);
505
Andreas Huberc6b59b72009-08-17 13:33:27 -0700506 node_id node = (void*)data.readIntPtr();
Andreas Huber693d2712009-08-14 14:37:10 -0700507 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
508
509 size_t size = data.readInt32();
510 void *params = const_cast<void *>(data.readInplace(size));
511
512 reply->writeInt32(set_config(node, index, params, size));
513
514 return NO_ERROR;
515 }
516
Andreas Huber20111aa2009-07-14 16:56:47 -0700517 case USE_BUFFER:
518 {
519 CHECK_INTERFACE(IOMX, data, reply);
520
Andreas Huberc6b59b72009-08-17 13:33:27 -0700521 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700522 OMX_U32 port_index = data.readInt32();
523 sp<IMemory> params =
524 interface_cast<IMemory>(data.readStrongBinder());
525
526 buffer_id buffer;
527 status_t err = use_buffer(node, port_index, params, &buffer);
528 reply->writeInt32(err);
529
530 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700531 reply->writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700532 }
533
534 return NO_ERROR;
535 }
536
537 case ALLOC_BUFFER:
538 {
539 CHECK_INTERFACE(IOMX, data, reply);
540
Andreas Huberc6b59b72009-08-17 13:33:27 -0700541 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700542 OMX_U32 port_index = data.readInt32();
543 size_t size = data.readInt32();
544
545 buffer_id buffer;
546 status_t err = allocate_buffer(node, port_index, size, &buffer);
547 reply->writeInt32(err);
548
549 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700550 reply->writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700551 }
552
553 return NO_ERROR;
554 }
555
556 case ALLOC_BUFFER_WITH_BACKUP:
557 {
558 CHECK_INTERFACE(IOMX, data, reply);
559
Andreas Huberc6b59b72009-08-17 13:33:27 -0700560 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700561 OMX_U32 port_index = data.readInt32();
562 sp<IMemory> params =
563 interface_cast<IMemory>(data.readStrongBinder());
564
565 buffer_id buffer;
566 status_t err = allocate_buffer_with_backup(
567 node, port_index, params, &buffer);
568
569 reply->writeInt32(err);
570
571 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700572 reply->writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700573 }
574
575 return NO_ERROR;
576 }
577
578 case FREE_BUFFER:
579 {
580 CHECK_INTERFACE(IOMX, data, reply);
581
Andreas Huberc6b59b72009-08-17 13:33:27 -0700582 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700583 OMX_U32 port_index = data.readInt32();
Andreas Huberc6b59b72009-08-17 13:33:27 -0700584 buffer_id buffer = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700585 reply->writeInt32(free_buffer(node, port_index, buffer));
586
587 return NO_ERROR;
588 }
589
Andreas Huber20111aa2009-07-14 16:56:47 -0700590 case OBSERVE_NODE:
591 {
592 CHECK_INTERFACE(IOMX, data, reply);
593
Andreas Huberc6b59b72009-08-17 13:33:27 -0700594 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700595 sp<IOMXObserver> observer =
596 interface_cast<IOMXObserver>(data.readStrongBinder());
597 reply->writeInt32(observe_node(node, observer));
598
599 return NO_ERROR;
600 }
601
602 case FILL_BUFFER:
603 {
604 CHECK_INTERFACE(IOMX, data, reply);
605
Andreas Huberc6b59b72009-08-17 13:33:27 -0700606 node_id node = (void*)data.readIntPtr();
607 buffer_id buffer = (void*)data.readIntPtr();
Andreas Huber36efa032009-10-08 11:02:27 -0700608 reply->writeInt32(fill_buffer(node, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -0700609
610 return NO_ERROR;
611 }
612
613 case EMPTY_BUFFER:
614 {
615 CHECK_INTERFACE(IOMX, data, reply);
616
Andreas Huberc6b59b72009-08-17 13:33:27 -0700617 node_id node = (void*)data.readIntPtr();
618 buffer_id buffer = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700619 OMX_U32 range_offset = data.readInt32();
620 OMX_U32 range_length = data.readInt32();
621 OMX_U32 flags = data.readInt32();
622 OMX_TICKS timestamp = data.readInt64();
623
Andreas Huber36efa032009-10-08 11:02:27 -0700624 reply->writeInt32(
625 empty_buffer(
626 node, buffer, range_offset, range_length,
627 flags, timestamp));
Andreas Huber20111aa2009-07-14 16:56:47 -0700628
629 return NO_ERROR;
630 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700631
Andreas Huber693d2712009-08-14 14:37:10 -0700632 case GET_EXTENSION_INDEX:
633 {
634 CHECK_INTERFACE(IOMX, data, reply);
635
Andreas Huberc6b59b72009-08-17 13:33:27 -0700636 node_id node = (void*)data.readIntPtr();
Andreas Huber693d2712009-08-14 14:37:10 -0700637 const char *parameter_name = data.readCString();
638
639 OMX_INDEXTYPE index;
640 status_t err = get_extension_index(node, parameter_name, &index);
641
642 reply->writeInt32(err);
643
644 if (err == OK) {
645 reply->writeInt32(index);
646 }
647
648 return OK;
649 }
650
Andreas Huber8b938cd2009-07-31 11:52:50 -0700651 case CREATE_RENDERER:
652 {
653 CHECK_INTERFACE(IOMX, data, reply);
654
655 sp<ISurface> isurface =
656 interface_cast<ISurface>(data.readStrongBinder());
657
658 const char *componentName = data.readCString();
659
660 OMX_COLOR_FORMATTYPE colorFormat =
661 static_cast<OMX_COLOR_FORMATTYPE>(data.readInt32());
662
663 size_t encodedWidth = (size_t)data.readInt32();
664 size_t encodedHeight = (size_t)data.readInt32();
665 size_t displayWidth = (size_t)data.readInt32();
666 size_t displayHeight = (size_t)data.readInt32();
667
668 sp<IOMXRenderer> renderer =
669 createRenderer(isurface, componentName, colorFormat,
670 encodedWidth, encodedHeight,
671 displayWidth, displayHeight);
672
673 reply->writeStrongBinder(renderer->asBinder());
674
675 return OK;
676 }
677
Andreas Huber20111aa2009-07-14 16:56:47 -0700678 default:
679 return BBinder::onTransact(code, data, reply, flags);
680 }
681}
682
683////////////////////////////////////////////////////////////////////////////////
684
685class BpOMXObserver : public BpInterface<IOMXObserver> {
686public:
687 BpOMXObserver(const sp<IBinder> &impl)
688 : BpInterface<IOMXObserver>(impl) {
689 }
690
691 virtual void on_message(const omx_message &msg) {
692 Parcel data, reply;
693 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
694 data.write(&msg, sizeof(msg));
695
696 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
697 }
698};
699
700IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
701
702status_t BnOMXObserver::onTransact(
703 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
704 switch (code) {
705 case OBSERVER_ON_MSG:
706 {
707 CHECK_INTERFACE(IOMXObserver, data, reply);
708
709 omx_message msg;
710 data.read(&msg, sizeof(msg));
711
712 // XXX Could use readInplace maybe?
713 on_message(msg);
714
715 return NO_ERROR;
716 }
717
718 default:
719 return BBinder::onTransact(code, data, reply, flags);
720 }
721}
722
Andreas Huber8b938cd2009-07-31 11:52:50 -0700723////////////////////////////////////////////////////////////////////////////////
724
725class BpOMXRenderer : public BpInterface<IOMXRenderer> {
726public:
727 BpOMXRenderer(const sp<IBinder> &impl)
728 : BpInterface<IOMXRenderer>(impl) {
729 }
730
731 virtual void render(IOMX::buffer_id buffer) {
732 Parcel data, reply;
733 data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700734 data.writeIntPtr((intptr_t)buffer);
Andreas Huber8b938cd2009-07-31 11:52:50 -0700735
736 // NOTE: Do NOT make this a ONE_WAY call, it must be synchronous
737 // so that the caller knows when to recycle the buffer.
738 remote()->transact(RENDERER_RENDER, data, &reply);
739 }
740};
741
742IMPLEMENT_META_INTERFACE(OMXRenderer, "android.hardware.IOMXRenderer");
743
744status_t BnOMXRenderer::onTransact(
745 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
746 switch (code) {
747 case RENDERER_RENDER:
748 {
749 CHECK_INTERFACE(IOMXRenderer, data, reply);
750
Andreas Huberc6b59b72009-08-17 13:33:27 -0700751 IOMX::buffer_id buffer = (void*)data.readIntPtr();
Andreas Huber8b938cd2009-07-31 11:52:50 -0700752
753 render(buffer);
754
755 return NO_ERROR;
756 }
757
758 default:
759 return BBinder::onTransact(code, data, reply, flags);
760 }
761}
762
Andreas Huber20111aa2009-07-14 16:56:47 -0700763} // namespace android