blob: b43e48fe859144241508e7357703f0d75612d70d [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,
Andreas Huber20111aa2009-07-14 16:56:47 -070027 FILL_BUFFER,
28 EMPTY_BUFFER,
Andreas Huber693d2712009-08-14 14:37:10 -070029 GET_EXTENSION_INDEX,
Andreas Huber8b938cd2009-07-31 11:52:50 -070030 CREATE_RENDERER,
Andreas Huber20111aa2009-07-14 16:56:47 -070031 OBSERVER_ON_MSG,
Andreas Huber8b938cd2009-07-31 11:52:50 -070032 RENDERER_RENDER,
Andreas Huber20111aa2009-07-14 16:56:47 -070033};
34
Andreas Huberf4148b52009-08-07 12:01:29 -070035sp<IOMXRenderer> IOMX::createRenderer(
36 const sp<Surface> &surface,
37 const char *componentName,
38 OMX_COLOR_FORMATTYPE colorFormat,
39 size_t encodedWidth, size_t encodedHeight,
40 size_t displayWidth, size_t displayHeight) {
41 return createRenderer(
42 surface->getISurface(),
43 componentName, colorFormat, encodedWidth, encodedHeight,
44 displayWidth, displayHeight);
45}
46
Andreas Huber1b84df12009-09-15 12:49:11 -070047sp<IOMXRenderer> IOMX::createRendererFromJavaSurface(
48 JNIEnv *env, jobject javaSurface,
49 const char *componentName,
50 OMX_COLOR_FORMATTYPE colorFormat,
51 size_t encodedWidth, size_t encodedHeight,
52 size_t displayWidth, size_t displayHeight) {
53 jclass surfaceClass = env->FindClass("android/view/Surface");
54 if (surfaceClass == NULL) {
55 LOGE("Can't find android/view/Surface");
56 return NULL;
57 }
58
59 jfieldID surfaceID = env->GetFieldID(surfaceClass, "mSurface", "I");
60 if (surfaceID == NULL) {
61 LOGE("Can't find Surface.mSurface");
62 return NULL;
63 }
64
65 sp<Surface> surface = (Surface *)env->GetIntField(javaSurface, surfaceID);
66
67 return createRenderer(
68 surface, componentName, colorFormat, encodedWidth,
69 encodedHeight, displayWidth, displayHeight);
70}
71
Andreas Huber20111aa2009-07-14 16:56:47 -070072class BpOMX : public BpInterface<IOMX> {
73public:
74 BpOMX(const sp<IBinder> &impl)
75 : BpInterface<IOMX>(impl) {
76 }
77
Andreas Huber134ee6a2009-12-16 09:30:55 -080078 virtual status_t listNodes(List<ComponentInfo> *list) {
Andreas Huber20111aa2009-07-14 16:56:47 -070079 list->clear();
80
81 Parcel data, reply;
82 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
83 remote()->transact(LIST_NODES, data, &reply);
84
85 int32_t n = reply.readInt32();
86 for (int32_t i = 0; i < n; ++i) {
Andreas Huber134ee6a2009-12-16 09:30:55 -080087 list->push_back(ComponentInfo());
88 ComponentInfo &info = *--list->end();
Andreas Huber20111aa2009-07-14 16:56:47 -070089
Andreas Huber134ee6a2009-12-16 09:30:55 -080090 info.mName = reply.readString8();
91 int32_t numRoles = reply.readInt32();
92 for (int32_t j = 0; j < numRoles; ++j) {
93 info.mRoles.push_back(reply.readString8());
94 }
Andreas Huber20111aa2009-07-14 16:56:47 -070095 }
96
97 return OK;
98 }
99
Andreas Huber318ad9c2009-10-15 13:46:54 -0700100 virtual status_t allocateNode(
101 const char *name, const sp<IOMXObserver> &observer, node_id *node) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700102 Parcel data, reply;
103 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
104 data.writeCString(name);
Andreas Huber318ad9c2009-10-15 13:46:54 -0700105 data.writeStrongBinder(observer->asBinder());
Andreas Huber20111aa2009-07-14 16:56:47 -0700106 remote()->transact(ALLOCATE_NODE, data, &reply);
107
108 status_t err = reply.readInt32();
109 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700110 *node = (void*)reply.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700111 } else {
112 *node = 0;
113 }
114
115 return err;
116 }
117
Andreas Huber318ad9c2009-10-15 13:46:54 -0700118 virtual status_t freeNode(node_id node) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700119 Parcel data, reply;
120 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700121 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700122 remote()->transact(FREE_NODE, data, &reply);
123
124 return reply.readInt32();
125 }
126
Andreas Huber318ad9c2009-10-15 13:46:54 -0700127 virtual status_t sendCommand(
Andreas Huber20111aa2009-07-14 16:56:47 -0700128 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
129 Parcel data, reply;
130 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700131 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700132 data.writeInt32(cmd);
133 data.writeInt32(param);
134 remote()->transact(SEND_COMMAND, data, &reply);
135
136 return reply.readInt32();
137 }
138
Andreas Huber318ad9c2009-10-15 13:46:54 -0700139 virtual status_t getParameter(
Andreas Huber20111aa2009-07-14 16:56:47 -0700140 node_id node, OMX_INDEXTYPE index,
141 void *params, size_t size) {
142 Parcel data, reply;
143 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700144 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700145 data.writeInt32(index);
146 data.writeInt32(size);
147 data.write(params, size);
148 remote()->transact(GET_PARAMETER, data, &reply);
149
150 status_t err = reply.readInt32();
151 if (err != OK) {
152 return err;
153 }
154
155 reply.read(params, size);
156
157 return OK;
158 }
159
Andreas Huber318ad9c2009-10-15 13:46:54 -0700160 virtual status_t setParameter(
Andreas Huber20111aa2009-07-14 16:56:47 -0700161 node_id node, OMX_INDEXTYPE index,
162 const void *params, size_t size) {
163 Parcel data, reply;
164 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700165 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700166 data.writeInt32(index);
167 data.writeInt32(size);
168 data.write(params, size);
169 remote()->transact(SET_PARAMETER, data, &reply);
170
171 return reply.readInt32();
172 }
173
Andreas Huber318ad9c2009-10-15 13:46:54 -0700174 virtual status_t getConfig(
Andreas Huber693d2712009-08-14 14:37:10 -0700175 node_id node, OMX_INDEXTYPE index,
176 void *params, size_t size) {
177 Parcel data, reply;
178 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700179 data.writeIntPtr((intptr_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700180 data.writeInt32(index);
181 data.writeInt32(size);
182 data.write(params, size);
183 remote()->transact(GET_CONFIG, data, &reply);
184
185 status_t err = reply.readInt32();
186 if (err != OK) {
187 return err;
188 }
189
190 reply.read(params, size);
191
192 return OK;
193 }
194
Andreas Huber318ad9c2009-10-15 13:46:54 -0700195 virtual status_t setConfig(
Andreas Huber693d2712009-08-14 14:37:10 -0700196 node_id node, OMX_INDEXTYPE index,
197 const void *params, size_t size) {
198 Parcel data, reply;
199 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700200 data.writeIntPtr((intptr_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700201 data.writeInt32(index);
202 data.writeInt32(size);
203 data.write(params, size);
204 remote()->transact(SET_CONFIG, data, &reply);
205
206 return reply.readInt32();
207 }
208
Andreas Huber318ad9c2009-10-15 13:46:54 -0700209 virtual status_t useBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700210 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
211 buffer_id *buffer) {
212 Parcel data, reply;
213 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700214 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700215 data.writeInt32(port_index);
216 data.writeStrongBinder(params->asBinder());
217 remote()->transact(USE_BUFFER, data, &reply);
218
219 status_t err = reply.readInt32();
220 if (err != OK) {
221 *buffer = 0;
222
223 return err;
224 }
225
Andreas Huberc6b59b72009-08-17 13:33:27 -0700226 *buffer = (void*)reply.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700227
228 return err;
229 }
230
Andreas Huber318ad9c2009-10-15 13:46:54 -0700231 virtual status_t allocateBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700232 node_id node, OMX_U32 port_index, size_t size,
233 buffer_id *buffer) {
234 Parcel data, reply;
235 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700236 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700237 data.writeInt32(port_index);
238 data.writeInt32(size);
239 remote()->transact(ALLOC_BUFFER, data, &reply);
240
241 status_t err = reply.readInt32();
242 if (err != OK) {
243 *buffer = 0;
244
245 return err;
246 }
247
Andreas Huberc6b59b72009-08-17 13:33:27 -0700248 *buffer = (void*)reply.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700249
250 return err;
251 }
252
Andreas Huber318ad9c2009-10-15 13:46:54 -0700253 virtual status_t allocateBufferWithBackup(
Andreas Huber20111aa2009-07-14 16:56:47 -0700254 node_id node, OMX_U32 port_index, const sp<IMemory> &params,
255 buffer_id *buffer) {
256 Parcel data, reply;
257 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700258 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700259 data.writeInt32(port_index);
260 data.writeStrongBinder(params->asBinder());
261 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
262
263 status_t err = reply.readInt32();
264 if (err != OK) {
265 *buffer = 0;
266
267 return err;
268 }
269
Andreas Huberc6b59b72009-08-17 13:33:27 -0700270 *buffer = (void*)reply.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700271
272 return err;
273 }
274
Andreas Huber318ad9c2009-10-15 13:46:54 -0700275 virtual status_t freeBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700276 node_id node, OMX_U32 port_index, buffer_id buffer) {
277 Parcel data, reply;
278 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700279 data.writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700280 data.writeInt32(port_index);
Andreas Huberc6b59b72009-08-17 13:33:27 -0700281 data.writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700282 remote()->transact(FREE_BUFFER, data, &reply);
283
284 return reply.readInt32();
285 }
286
Andreas Huber318ad9c2009-10-15 13:46:54 -0700287 virtual status_t fillBuffer(node_id node, buffer_id buffer) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700288 Parcel data, reply;
289 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700290 data.writeIntPtr((intptr_t)node);
291 data.writeIntPtr((intptr_t)buffer);
Andreas Huber36efa032009-10-08 11:02:27 -0700292 remote()->transact(FILL_BUFFER, data, &reply);
293
294 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700295 }
296
Andreas Huber318ad9c2009-10-15 13:46:54 -0700297 virtual status_t emptyBuffer(
Andreas Huber20111aa2009-07-14 16:56:47 -0700298 node_id node,
299 buffer_id buffer,
300 OMX_U32 range_offset, OMX_U32 range_length,
301 OMX_U32 flags, OMX_TICKS timestamp) {
302 Parcel data, reply;
303 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700304 data.writeIntPtr((intptr_t)node);
305 data.writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700306 data.writeInt32(range_offset);
307 data.writeInt32(range_length);
308 data.writeInt32(flags);
309 data.writeInt64(timestamp);
Andreas Huber36efa032009-10-08 11:02:27 -0700310 remote()->transact(EMPTY_BUFFER, data, &reply);
311
312 return reply.readInt32();
Andreas Huber20111aa2009-07-14 16:56:47 -0700313 }
Andreas Huber8b938cd2009-07-31 11:52:50 -0700314
Andreas Huber318ad9c2009-10-15 13:46:54 -0700315 virtual status_t getExtensionIndex(
Andreas Huber693d2712009-08-14 14:37:10 -0700316 node_id node,
317 const char *parameter_name,
318 OMX_INDEXTYPE *index) {
319 Parcel data, reply;
320 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700321 data.writeIntPtr((intptr_t)node);
Andreas Huber693d2712009-08-14 14:37:10 -0700322 data.writeCString(parameter_name);
323
324 remote()->transact(GET_EXTENSION_INDEX, data, &reply);
325
326 status_t err = reply.readInt32();
327 if (err == OK) {
328 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32());
329 } else {
330 *index = OMX_IndexComponentStartUnused;
331 }
332
333 return err;
334 }
335
Andreas Huber8b938cd2009-07-31 11:52:50 -0700336 virtual sp<IOMXRenderer> createRenderer(
337 const sp<ISurface> &surface,
338 const char *componentName,
339 OMX_COLOR_FORMATTYPE colorFormat,
340 size_t encodedWidth, size_t encodedHeight,
341 size_t displayWidth, size_t displayHeight) {
342 Parcel data, reply;
343 data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
344
345 data.writeStrongBinder(surface->asBinder());
346 data.writeCString(componentName);
347 data.writeInt32(colorFormat);
348 data.writeInt32(encodedWidth);
349 data.writeInt32(encodedHeight);
350 data.writeInt32(displayWidth);
351 data.writeInt32(displayHeight);
352
353 remote()->transact(CREATE_RENDERER, data, &reply);
354
355 return interface_cast<IOMXRenderer>(reply.readStrongBinder());
356 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700357};
358
359IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX");
360
361////////////////////////////////////////////////////////////////////////////////
362
363#define CHECK_INTERFACE(interface, data, reply) \
364 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
365 LOGW("Call incorrectly routed to " #interface); \
366 return PERMISSION_DENIED; \
367 } } while (0)
368
369status_t BnOMX::onTransact(
370 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
371 switch (code) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700372 case LIST_NODES:
373 {
374 CHECK_INTERFACE(IOMX, data, reply);
375
Andreas Huber134ee6a2009-12-16 09:30:55 -0800376 List<ComponentInfo> list;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700377 listNodes(&list);
Andreas Huber20111aa2009-07-14 16:56:47 -0700378
379 reply->writeInt32(list.size());
Andreas Huber134ee6a2009-12-16 09:30:55 -0800380 for (List<ComponentInfo>::iterator it = list.begin();
Andreas Huber20111aa2009-07-14 16:56:47 -0700381 it != list.end(); ++it) {
Andreas Huber134ee6a2009-12-16 09:30:55 -0800382 ComponentInfo &cur = *it;
383
384 reply->writeString8(cur.mName);
385 reply->writeInt32(cur.mRoles.size());
386 for (List<String8>::iterator role_it = cur.mRoles.begin();
387 role_it != cur.mRoles.end(); ++role_it) {
388 reply->writeString8(*role_it);
389 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700390 }
391
392 return NO_ERROR;
393 }
394
395 case ALLOCATE_NODE:
396 {
397 CHECK_INTERFACE(IOMX, data, reply);
398
Andreas Huber318ad9c2009-10-15 13:46:54 -0700399 const char *name = data.readCString();
400
401 sp<IOMXObserver> observer =
402 interface_cast<IOMXObserver>(data.readStrongBinder());
403
Andreas Huber20111aa2009-07-14 16:56:47 -0700404 node_id node;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700405
406 status_t err = allocateNode(name, observer, &node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700407 reply->writeInt32(err);
408 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700409 reply->writeIntPtr((intptr_t)node);
Andreas Huber20111aa2009-07-14 16:56:47 -0700410 }
411
412 return NO_ERROR;
413 }
414
415 case FREE_NODE:
416 {
417 CHECK_INTERFACE(IOMX, data, reply);
418
Andreas Huberc6b59b72009-08-17 13:33:27 -0700419 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700420
Andreas Huber318ad9c2009-10-15 13:46:54 -0700421 reply->writeInt32(freeNode(node));
Andreas Huber20111aa2009-07-14 16:56:47 -0700422
423 return NO_ERROR;
424 }
425
426 case SEND_COMMAND:
427 {
428 CHECK_INTERFACE(IOMX, data, reply);
429
Andreas Huberc6b59b72009-08-17 13:33:27 -0700430 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700431
432 OMX_COMMANDTYPE cmd =
433 static_cast<OMX_COMMANDTYPE>(data.readInt32());
434
435 OMX_S32 param = data.readInt32();
Andreas Huber318ad9c2009-10-15 13:46:54 -0700436 reply->writeInt32(sendCommand(node, cmd, param));
Andreas Huber20111aa2009-07-14 16:56:47 -0700437
438 return NO_ERROR;
439 }
440
441 case GET_PARAMETER:
442 {
443 CHECK_INTERFACE(IOMX, data, reply);
444
Andreas Huberc6b59b72009-08-17 13:33:27 -0700445 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700446 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
447
448 size_t size = data.readInt32();
449
450 // XXX I am not happy with this but Parcel::readInplace didn't work.
451 void *params = malloc(size);
452 data.read(params, size);
453
Andreas Huber318ad9c2009-10-15 13:46:54 -0700454 status_t err = getParameter(node, index, params, size);
Andreas Huber20111aa2009-07-14 16:56:47 -0700455
456 reply->writeInt32(err);
457
458 if (err == OK) {
459 reply->write(params, size);
460 }
461
462 free(params);
463 params = NULL;
464
465 return NO_ERROR;
466 }
467
468 case SET_PARAMETER:
469 {
470 CHECK_INTERFACE(IOMX, data, reply);
471
Andreas Huberc6b59b72009-08-17 13:33:27 -0700472 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700473 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
474
475 size_t size = data.readInt32();
476 void *params = const_cast<void *>(data.readInplace(size));
477
Andreas Huber318ad9c2009-10-15 13:46:54 -0700478 reply->writeInt32(setParameter(node, index, params, size));
Andreas Huber20111aa2009-07-14 16:56:47 -0700479
480 return NO_ERROR;
481 }
482
Andreas Huber693d2712009-08-14 14:37:10 -0700483 case GET_CONFIG:
484 {
485 CHECK_INTERFACE(IOMX, data, reply);
486
Andreas Huberc6b59b72009-08-17 13:33:27 -0700487 node_id node = (void*)data.readIntPtr();
Andreas Huber693d2712009-08-14 14:37:10 -0700488 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
489
490 size_t size = data.readInt32();
491
492 // XXX I am not happy with this but Parcel::readInplace didn't work.
493 void *params = malloc(size);
494 data.read(params, size);
495
Andreas Huber318ad9c2009-10-15 13:46:54 -0700496 status_t err = getConfig(node, index, params, size);
Andreas Huber693d2712009-08-14 14:37:10 -0700497
498 reply->writeInt32(err);
499
500 if (err == OK) {
501 reply->write(params, size);
502 }
503
504 free(params);
505 params = NULL;
506
507 return NO_ERROR;
508 }
509
510 case SET_CONFIG:
511 {
512 CHECK_INTERFACE(IOMX, data, reply);
513
Andreas Huberc6b59b72009-08-17 13:33:27 -0700514 node_id node = (void*)data.readIntPtr();
Andreas Huber693d2712009-08-14 14:37:10 -0700515 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
516
517 size_t size = data.readInt32();
518 void *params = const_cast<void *>(data.readInplace(size));
519
Andreas Huber318ad9c2009-10-15 13:46:54 -0700520 reply->writeInt32(setConfig(node, index, params, size));
Andreas Huber693d2712009-08-14 14:37:10 -0700521
522 return NO_ERROR;
523 }
524
Andreas Huber20111aa2009-07-14 16:56:47 -0700525 case USE_BUFFER:
526 {
527 CHECK_INTERFACE(IOMX, data, reply);
528
Andreas Huberc6b59b72009-08-17 13:33:27 -0700529 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700530 OMX_U32 port_index = data.readInt32();
531 sp<IMemory> params =
532 interface_cast<IMemory>(data.readStrongBinder());
533
534 buffer_id buffer;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700535 status_t err = useBuffer(node, port_index, params, &buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700536 reply->writeInt32(err);
537
538 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700539 reply->writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700540 }
541
542 return NO_ERROR;
543 }
544
545 case ALLOC_BUFFER:
546 {
547 CHECK_INTERFACE(IOMX, data, reply);
548
Andreas Huberc6b59b72009-08-17 13:33:27 -0700549 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700550 OMX_U32 port_index = data.readInt32();
551 size_t size = data.readInt32();
552
553 buffer_id buffer;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700554 status_t err = allocateBuffer(node, port_index, size, &buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700555 reply->writeInt32(err);
556
557 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700558 reply->writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700559 }
560
561 return NO_ERROR;
562 }
563
564 case ALLOC_BUFFER_WITH_BACKUP:
565 {
566 CHECK_INTERFACE(IOMX, data, reply);
567
Andreas Huberc6b59b72009-08-17 13:33:27 -0700568 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700569 OMX_U32 port_index = data.readInt32();
570 sp<IMemory> params =
571 interface_cast<IMemory>(data.readStrongBinder());
572
573 buffer_id buffer;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700574 status_t err = allocateBufferWithBackup(
Andreas Huber20111aa2009-07-14 16:56:47 -0700575 node, port_index, params, &buffer);
576
577 reply->writeInt32(err);
578
579 if (err == OK) {
Andreas Huberc6b59b72009-08-17 13:33:27 -0700580 reply->writeIntPtr((intptr_t)buffer);
Andreas Huber20111aa2009-07-14 16:56:47 -0700581 }
582
583 return NO_ERROR;
584 }
585
586 case FREE_BUFFER:
587 {
588 CHECK_INTERFACE(IOMX, data, reply);
589
Andreas Huberc6b59b72009-08-17 13:33:27 -0700590 node_id node = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700591 OMX_U32 port_index = data.readInt32();
Andreas Huberc6b59b72009-08-17 13:33:27 -0700592 buffer_id buffer = (void*)data.readIntPtr();
Andreas Huber318ad9c2009-10-15 13:46:54 -0700593 reply->writeInt32(freeBuffer(node, port_index, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -0700594
595 return NO_ERROR;
596 }
597
598 case FILL_BUFFER:
599 {
600 CHECK_INTERFACE(IOMX, data, reply);
601
Andreas Huberc6b59b72009-08-17 13:33:27 -0700602 node_id node = (void*)data.readIntPtr();
603 buffer_id buffer = (void*)data.readIntPtr();
Andreas Huber318ad9c2009-10-15 13:46:54 -0700604 reply->writeInt32(fillBuffer(node, buffer));
Andreas Huber20111aa2009-07-14 16:56:47 -0700605
606 return NO_ERROR;
607 }
608
609 case EMPTY_BUFFER:
610 {
611 CHECK_INTERFACE(IOMX, data, reply);
612
Andreas Huberc6b59b72009-08-17 13:33:27 -0700613 node_id node = (void*)data.readIntPtr();
614 buffer_id buffer = (void*)data.readIntPtr();
Andreas Huber20111aa2009-07-14 16:56:47 -0700615 OMX_U32 range_offset = data.readInt32();
616 OMX_U32 range_length = data.readInt32();
617 OMX_U32 flags = data.readInt32();
618 OMX_TICKS timestamp = data.readInt64();
619
Andreas Huber36efa032009-10-08 11:02:27 -0700620 reply->writeInt32(
Andreas Huber318ad9c2009-10-15 13:46:54 -0700621 emptyBuffer(
Andreas Huber36efa032009-10-08 11:02:27 -0700622 node, buffer, range_offset, range_length,
623 flags, timestamp));
Andreas Huber20111aa2009-07-14 16:56:47 -0700624
625 return NO_ERROR;
626 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700627
Andreas Huber693d2712009-08-14 14:37:10 -0700628 case GET_EXTENSION_INDEX:
629 {
630 CHECK_INTERFACE(IOMX, data, reply);
631
Andreas Huberc6b59b72009-08-17 13:33:27 -0700632 node_id node = (void*)data.readIntPtr();
Andreas Huber693d2712009-08-14 14:37:10 -0700633 const char *parameter_name = data.readCString();
634
635 OMX_INDEXTYPE index;
Andreas Huber318ad9c2009-10-15 13:46:54 -0700636 status_t err = getExtensionIndex(node, parameter_name, &index);
Andreas Huber693d2712009-08-14 14:37:10 -0700637
638 reply->writeInt32(err);
639
640 if (err == OK) {
641 reply->writeInt32(index);
642 }
643
644 return OK;
645 }
646
Andreas Huber8b938cd2009-07-31 11:52:50 -0700647 case CREATE_RENDERER:
648 {
649 CHECK_INTERFACE(IOMX, data, reply);
650
651 sp<ISurface> isurface =
652 interface_cast<ISurface>(data.readStrongBinder());
653
654 const char *componentName = data.readCString();
655
656 OMX_COLOR_FORMATTYPE colorFormat =
657 static_cast<OMX_COLOR_FORMATTYPE>(data.readInt32());
658
659 size_t encodedWidth = (size_t)data.readInt32();
660 size_t encodedHeight = (size_t)data.readInt32();
661 size_t displayWidth = (size_t)data.readInt32();
662 size_t displayHeight = (size_t)data.readInt32();
663
664 sp<IOMXRenderer> renderer =
665 createRenderer(isurface, componentName, colorFormat,
666 encodedWidth, encodedHeight,
667 displayWidth, displayHeight);
668
669 reply->writeStrongBinder(renderer->asBinder());
670
671 return OK;
672 }
673
Andreas Huber20111aa2009-07-14 16:56:47 -0700674 default:
675 return BBinder::onTransact(code, data, reply, flags);
676 }
677}
678
679////////////////////////////////////////////////////////////////////////////////
680
681class BpOMXObserver : public BpInterface<IOMXObserver> {
682public:
683 BpOMXObserver(const sp<IBinder> &impl)
684 : BpInterface<IOMXObserver>(impl) {
685 }
686
Andreas Huber318ad9c2009-10-15 13:46:54 -0700687 virtual void onMessage(const omx_message &msg) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700688 Parcel data, reply;
689 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
690 data.write(&msg, sizeof(msg));
691
692 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
693 }
694};
695
696IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver");
697
698status_t BnOMXObserver::onTransact(
699 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
700 switch (code) {
701 case OBSERVER_ON_MSG:
702 {
703 CHECK_INTERFACE(IOMXObserver, data, reply);
704
705 omx_message msg;
706 data.read(&msg, sizeof(msg));
707
708 // XXX Could use readInplace maybe?
Andreas Huber318ad9c2009-10-15 13:46:54 -0700709 onMessage(msg);
Andreas Huber20111aa2009-07-14 16:56:47 -0700710
711 return NO_ERROR;
712 }
713
714 default:
715 return BBinder::onTransact(code, data, reply, flags);
716 }
717}
718
Andreas Huber8b938cd2009-07-31 11:52:50 -0700719////////////////////////////////////////////////////////////////////////////////
720
721class BpOMXRenderer : public BpInterface<IOMXRenderer> {
722public:
723 BpOMXRenderer(const sp<IBinder> &impl)
724 : BpInterface<IOMXRenderer>(impl) {
725 }
726
727 virtual void render(IOMX::buffer_id buffer) {
728 Parcel data, reply;
729 data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor());
Andreas Huberc6b59b72009-08-17 13:33:27 -0700730 data.writeIntPtr((intptr_t)buffer);
Andreas Huber8b938cd2009-07-31 11:52:50 -0700731
732 // NOTE: Do NOT make this a ONE_WAY call, it must be synchronous
733 // so that the caller knows when to recycle the buffer.
734 remote()->transact(RENDERER_RENDER, data, &reply);
735 }
736};
737
738IMPLEMENT_META_INTERFACE(OMXRenderer, "android.hardware.IOMXRenderer");
739
740status_t BnOMXRenderer::onTransact(
741 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
742 switch (code) {
743 case RENDERER_RENDER:
744 {
745 CHECK_INTERFACE(IOMXRenderer, data, reply);
746
Andreas Huberc6b59b72009-08-17 13:33:27 -0700747 IOMX::buffer_id buffer = (void*)data.readIntPtr();
Andreas Huber8b938cd2009-07-31 11:52:50 -0700748
749 render(buffer);
750
751 return NO_ERROR;
752 }
753
754 default:
755 return BBinder::onTransact(code, data, reply, flags);
756 }
757}
758
Andreas Huber20111aa2009-07-14 16:56:47 -0700759} // namespace android