IOMX.cpp revision 9f2d258645826c999a93a4206df157fec2e3b0f2
1//#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> 8#include <surfaceflinger/ISurface.h> 9#include <surfaceflinger/Surface.h> 10 11namespace android { 12 13enum { 14 CONNECT = IBinder::FIRST_CALL_TRANSACTION, 15 LIVES_LOCALLY, 16 LIST_NODES, 17 ALLOCATE_NODE, 18 FREE_NODE, 19 SEND_COMMAND, 20 GET_PARAMETER, 21 SET_PARAMETER, 22 GET_CONFIG, 23 SET_CONFIG, 24 USE_BUFFER, 25 ALLOC_BUFFER, 26 ALLOC_BUFFER_WITH_BACKUP, 27 FREE_BUFFER, 28 FILL_BUFFER, 29 EMPTY_BUFFER, 30 GET_EXTENSION_INDEX, 31 CREATE_RENDERER, 32 OBSERVER_ON_MSG, 33 RENDERER_RENDER, 34}; 35 36sp<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 48sp<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, ANDROID_VIEW_SURFACE_JNI_ID, "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 73class BpOMX : public BpInterface<IOMX> { 74public: 75 BpOMX(const sp<IBinder> &impl) 76 : BpInterface<IOMX>(impl) { 77 } 78 79 virtual bool livesLocally(pid_t pid) { 80 Parcel data, reply; 81 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 82 data.writeInt32(pid); 83 remote()->transact(LIVES_LOCALLY, data, &reply); 84 85 return reply.readInt32() != 0; 86 } 87 88 virtual status_t listNodes(List<ComponentInfo> *list) { 89 list->clear(); 90 91 Parcel data, reply; 92 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 93 remote()->transact(LIST_NODES, data, &reply); 94 95 int32_t n = reply.readInt32(); 96 for (int32_t i = 0; i < n; ++i) { 97 list->push_back(ComponentInfo()); 98 ComponentInfo &info = *--list->end(); 99 100 info.mName = reply.readString8(); 101 int32_t numRoles = reply.readInt32(); 102 for (int32_t j = 0; j < numRoles; ++j) { 103 info.mRoles.push_back(reply.readString8()); 104 } 105 } 106 107 return OK; 108 } 109 110 virtual status_t allocateNode( 111 const char *name, const sp<IOMXObserver> &observer, node_id *node) { 112 Parcel data, reply; 113 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 114 data.writeCString(name); 115 data.writeStrongBinder(observer->asBinder()); 116 remote()->transact(ALLOCATE_NODE, data, &reply); 117 118 status_t err = reply.readInt32(); 119 if (err == OK) { 120 *node = (void*)reply.readIntPtr(); 121 } else { 122 *node = 0; 123 } 124 125 return err; 126 } 127 128 virtual status_t freeNode(node_id node) { 129 Parcel data, reply; 130 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 131 data.writeIntPtr((intptr_t)node); 132 remote()->transact(FREE_NODE, data, &reply); 133 134 return reply.readInt32(); 135 } 136 137 virtual status_t sendCommand( 138 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { 139 Parcel data, reply; 140 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 141 data.writeIntPtr((intptr_t)node); 142 data.writeInt32(cmd); 143 data.writeInt32(param); 144 remote()->transact(SEND_COMMAND, data, &reply); 145 146 return reply.readInt32(); 147 } 148 149 virtual status_t getParameter( 150 node_id node, OMX_INDEXTYPE index, 151 void *params, size_t size) { 152 Parcel data, reply; 153 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 154 data.writeIntPtr((intptr_t)node); 155 data.writeInt32(index); 156 data.writeInt32(size); 157 data.write(params, size); 158 remote()->transact(GET_PARAMETER, data, &reply); 159 160 status_t err = reply.readInt32(); 161 if (err != OK) { 162 return err; 163 } 164 165 reply.read(params, size); 166 167 return OK; 168 } 169 170 virtual status_t setParameter( 171 node_id node, OMX_INDEXTYPE index, 172 const void *params, size_t size) { 173 Parcel data, reply; 174 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 175 data.writeIntPtr((intptr_t)node); 176 data.writeInt32(index); 177 data.writeInt32(size); 178 data.write(params, size); 179 remote()->transact(SET_PARAMETER, data, &reply); 180 181 return reply.readInt32(); 182 } 183 184 virtual status_t getConfig( 185 node_id node, OMX_INDEXTYPE index, 186 void *params, size_t size) { 187 Parcel data, reply; 188 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 189 data.writeIntPtr((intptr_t)node); 190 data.writeInt32(index); 191 data.writeInt32(size); 192 data.write(params, size); 193 remote()->transact(GET_CONFIG, data, &reply); 194 195 status_t err = reply.readInt32(); 196 if (err != OK) { 197 return err; 198 } 199 200 reply.read(params, size); 201 202 return OK; 203 } 204 205 virtual status_t setConfig( 206 node_id node, OMX_INDEXTYPE index, 207 const void *params, size_t size) { 208 Parcel data, reply; 209 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 210 data.writeIntPtr((intptr_t)node); 211 data.writeInt32(index); 212 data.writeInt32(size); 213 data.write(params, size); 214 remote()->transact(SET_CONFIG, data, &reply); 215 216 return reply.readInt32(); 217 } 218 219 virtual status_t useBuffer( 220 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 221 buffer_id *buffer) { 222 Parcel data, reply; 223 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 224 data.writeIntPtr((intptr_t)node); 225 data.writeInt32(port_index); 226 data.writeStrongBinder(params->asBinder()); 227 remote()->transact(USE_BUFFER, data, &reply); 228 229 status_t err = reply.readInt32(); 230 if (err != OK) { 231 *buffer = 0; 232 233 return err; 234 } 235 236 *buffer = (void*)reply.readIntPtr(); 237 238 return err; 239 } 240 241 virtual status_t allocateBuffer( 242 node_id node, OMX_U32 port_index, size_t size, 243 buffer_id *buffer, void **buffer_data) { 244 Parcel data, reply; 245 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 246 data.writeIntPtr((intptr_t)node); 247 data.writeInt32(port_index); 248 data.writeInt32(size); 249 remote()->transact(ALLOC_BUFFER, data, &reply); 250 251 status_t err = reply.readInt32(); 252 if (err != OK) { 253 *buffer = 0; 254 255 return err; 256 } 257 258 *buffer = (void *)reply.readIntPtr(); 259 *buffer_data = (void *)reply.readIntPtr(); 260 261 return err; 262 } 263 264 virtual status_t allocateBufferWithBackup( 265 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 266 buffer_id *buffer) { 267 Parcel data, reply; 268 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 269 data.writeIntPtr((intptr_t)node); 270 data.writeInt32(port_index); 271 data.writeStrongBinder(params->asBinder()); 272 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply); 273 274 status_t err = reply.readInt32(); 275 if (err != OK) { 276 *buffer = 0; 277 278 return err; 279 } 280 281 *buffer = (void*)reply.readIntPtr(); 282 283 return err; 284 } 285 286 virtual status_t freeBuffer( 287 node_id node, OMX_U32 port_index, buffer_id buffer) { 288 Parcel data, reply; 289 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 290 data.writeIntPtr((intptr_t)node); 291 data.writeInt32(port_index); 292 data.writeIntPtr((intptr_t)buffer); 293 remote()->transact(FREE_BUFFER, data, &reply); 294 295 return reply.readInt32(); 296 } 297 298 virtual status_t fillBuffer(node_id node, buffer_id buffer) { 299 Parcel data, reply; 300 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 301 data.writeIntPtr((intptr_t)node); 302 data.writeIntPtr((intptr_t)buffer); 303 remote()->transact(FILL_BUFFER, data, &reply); 304 305 return reply.readInt32(); 306 } 307 308 virtual status_t emptyBuffer( 309 node_id node, 310 buffer_id buffer, 311 OMX_U32 range_offset, OMX_U32 range_length, 312 OMX_U32 flags, OMX_TICKS timestamp) { 313 Parcel data, reply; 314 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 315 data.writeIntPtr((intptr_t)node); 316 data.writeIntPtr((intptr_t)buffer); 317 data.writeInt32(range_offset); 318 data.writeInt32(range_length); 319 data.writeInt32(flags); 320 data.writeInt64(timestamp); 321 remote()->transact(EMPTY_BUFFER, data, &reply); 322 323 return reply.readInt32(); 324 } 325 326 virtual status_t getExtensionIndex( 327 node_id node, 328 const char *parameter_name, 329 OMX_INDEXTYPE *index) { 330 Parcel data, reply; 331 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 332 data.writeIntPtr((intptr_t)node); 333 data.writeCString(parameter_name); 334 335 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 336 337 status_t err = reply.readInt32(); 338 if (err == OK) { 339 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 340 } else { 341 *index = OMX_IndexComponentStartUnused; 342 } 343 344 return err; 345 } 346 347 virtual sp<IOMXRenderer> createRenderer( 348 const sp<ISurface> &surface, 349 const char *componentName, 350 OMX_COLOR_FORMATTYPE colorFormat, 351 size_t encodedWidth, size_t encodedHeight, 352 size_t displayWidth, size_t displayHeight) { 353 Parcel data, reply; 354 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 355 356 data.writeStrongBinder(surface->asBinder()); 357 data.writeCString(componentName); 358 data.writeInt32(colorFormat); 359 data.writeInt32(encodedWidth); 360 data.writeInt32(encodedHeight); 361 data.writeInt32(displayWidth); 362 data.writeInt32(displayHeight); 363 364 remote()->transact(CREATE_RENDERER, data, &reply); 365 366 return interface_cast<IOMXRenderer>(reply.readStrongBinder()); 367 } 368}; 369 370IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); 371 372//////////////////////////////////////////////////////////////////////////////// 373 374#define CHECK_INTERFACE(interface, data, reply) \ 375 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 376 LOGW("Call incorrectly routed to " #interface); \ 377 return PERMISSION_DENIED; \ 378 } } while (0) 379 380status_t BnOMX::onTransact( 381 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 382 switch (code) { 383 case LIVES_LOCALLY: 384 { 385 CHECK_INTERFACE(IOMX, data, reply); 386 reply->writeInt32(livesLocally((pid_t)data.readInt32())); 387 388 return OK; 389 } 390 391 case LIST_NODES: 392 { 393 CHECK_INTERFACE(IOMX, data, reply); 394 395 List<ComponentInfo> list; 396 listNodes(&list); 397 398 reply->writeInt32(list.size()); 399 for (List<ComponentInfo>::iterator it = list.begin(); 400 it != list.end(); ++it) { 401 ComponentInfo &cur = *it; 402 403 reply->writeString8(cur.mName); 404 reply->writeInt32(cur.mRoles.size()); 405 for (List<String8>::iterator role_it = cur.mRoles.begin(); 406 role_it != cur.mRoles.end(); ++role_it) { 407 reply->writeString8(*role_it); 408 } 409 } 410 411 return NO_ERROR; 412 } 413 414 case ALLOCATE_NODE: 415 { 416 CHECK_INTERFACE(IOMX, data, reply); 417 418 const char *name = data.readCString(); 419 420 sp<IOMXObserver> observer = 421 interface_cast<IOMXObserver>(data.readStrongBinder()); 422 423 node_id node; 424 425 status_t err = allocateNode(name, observer, &node); 426 reply->writeInt32(err); 427 if (err == OK) { 428 reply->writeIntPtr((intptr_t)node); 429 } 430 431 return NO_ERROR; 432 } 433 434 case FREE_NODE: 435 { 436 CHECK_INTERFACE(IOMX, data, reply); 437 438 node_id node = (void*)data.readIntPtr(); 439 440 reply->writeInt32(freeNode(node)); 441 442 return NO_ERROR; 443 } 444 445 case SEND_COMMAND: 446 { 447 CHECK_INTERFACE(IOMX, data, reply); 448 449 node_id node = (void*)data.readIntPtr(); 450 451 OMX_COMMANDTYPE cmd = 452 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 453 454 OMX_S32 param = data.readInt32(); 455 reply->writeInt32(sendCommand(node, cmd, param)); 456 457 return NO_ERROR; 458 } 459 460 case GET_PARAMETER: 461 { 462 CHECK_INTERFACE(IOMX, data, reply); 463 464 node_id node = (void*)data.readIntPtr(); 465 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 466 467 size_t size = data.readInt32(); 468 469 // XXX I am not happy with this but Parcel::readInplace didn't work. 470 void *params = malloc(size); 471 data.read(params, size); 472 473 status_t err = getParameter(node, index, params, size); 474 475 reply->writeInt32(err); 476 477 if (err == OK) { 478 reply->write(params, size); 479 } 480 481 free(params); 482 params = NULL; 483 484 return NO_ERROR; 485 } 486 487 case SET_PARAMETER: 488 { 489 CHECK_INTERFACE(IOMX, data, reply); 490 491 node_id node = (void*)data.readIntPtr(); 492 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 493 494 size_t size = data.readInt32(); 495 void *params = const_cast<void *>(data.readInplace(size)); 496 497 reply->writeInt32(setParameter(node, index, params, size)); 498 499 return NO_ERROR; 500 } 501 502 case GET_CONFIG: 503 { 504 CHECK_INTERFACE(IOMX, data, reply); 505 506 node_id node = (void*)data.readIntPtr(); 507 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 508 509 size_t size = data.readInt32(); 510 511 // XXX I am not happy with this but Parcel::readInplace didn't work. 512 void *params = malloc(size); 513 data.read(params, size); 514 515 status_t err = getConfig(node, index, params, size); 516 517 reply->writeInt32(err); 518 519 if (err == OK) { 520 reply->write(params, size); 521 } 522 523 free(params); 524 params = NULL; 525 526 return NO_ERROR; 527 } 528 529 case SET_CONFIG: 530 { 531 CHECK_INTERFACE(IOMX, data, reply); 532 533 node_id node = (void*)data.readIntPtr(); 534 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 535 536 size_t size = data.readInt32(); 537 void *params = const_cast<void *>(data.readInplace(size)); 538 539 reply->writeInt32(setConfig(node, index, params, size)); 540 541 return NO_ERROR; 542 } 543 544 case USE_BUFFER: 545 { 546 CHECK_INTERFACE(IOMX, data, reply); 547 548 node_id node = (void*)data.readIntPtr(); 549 OMX_U32 port_index = data.readInt32(); 550 sp<IMemory> params = 551 interface_cast<IMemory>(data.readStrongBinder()); 552 553 buffer_id buffer; 554 status_t err = useBuffer(node, port_index, params, &buffer); 555 reply->writeInt32(err); 556 557 if (err == OK) { 558 reply->writeIntPtr((intptr_t)buffer); 559 } 560 561 return NO_ERROR; 562 } 563 564 case ALLOC_BUFFER: 565 { 566 CHECK_INTERFACE(IOMX, data, reply); 567 568 node_id node = (void*)data.readIntPtr(); 569 OMX_U32 port_index = data.readInt32(); 570 size_t size = data.readInt32(); 571 572 buffer_id buffer; 573 void *buffer_data; 574 status_t err = allocateBuffer( 575 node, port_index, size, &buffer, &buffer_data); 576 reply->writeInt32(err); 577 578 if (err == OK) { 579 reply->writeIntPtr((intptr_t)buffer); 580 reply->writeIntPtr((intptr_t)buffer_data); 581 } 582 583 return NO_ERROR; 584 } 585 586 case ALLOC_BUFFER_WITH_BACKUP: 587 { 588 CHECK_INTERFACE(IOMX, data, reply); 589 590 node_id node = (void*)data.readIntPtr(); 591 OMX_U32 port_index = data.readInt32(); 592 sp<IMemory> params = 593 interface_cast<IMemory>(data.readStrongBinder()); 594 595 buffer_id buffer; 596 status_t err = allocateBufferWithBackup( 597 node, port_index, params, &buffer); 598 599 reply->writeInt32(err); 600 601 if (err == OK) { 602 reply->writeIntPtr((intptr_t)buffer); 603 } 604 605 return NO_ERROR; 606 } 607 608 case FREE_BUFFER: 609 { 610 CHECK_INTERFACE(IOMX, data, reply); 611 612 node_id node = (void*)data.readIntPtr(); 613 OMX_U32 port_index = data.readInt32(); 614 buffer_id buffer = (void*)data.readIntPtr(); 615 reply->writeInt32(freeBuffer(node, port_index, buffer)); 616 617 return NO_ERROR; 618 } 619 620 case FILL_BUFFER: 621 { 622 CHECK_INTERFACE(IOMX, data, reply); 623 624 node_id node = (void*)data.readIntPtr(); 625 buffer_id buffer = (void*)data.readIntPtr(); 626 reply->writeInt32(fillBuffer(node, buffer)); 627 628 return NO_ERROR; 629 } 630 631 case EMPTY_BUFFER: 632 { 633 CHECK_INTERFACE(IOMX, data, reply); 634 635 node_id node = (void*)data.readIntPtr(); 636 buffer_id buffer = (void*)data.readIntPtr(); 637 OMX_U32 range_offset = data.readInt32(); 638 OMX_U32 range_length = data.readInt32(); 639 OMX_U32 flags = data.readInt32(); 640 OMX_TICKS timestamp = data.readInt64(); 641 642 reply->writeInt32( 643 emptyBuffer( 644 node, buffer, range_offset, range_length, 645 flags, timestamp)); 646 647 return NO_ERROR; 648 } 649 650 case GET_EXTENSION_INDEX: 651 { 652 CHECK_INTERFACE(IOMX, data, reply); 653 654 node_id node = (void*)data.readIntPtr(); 655 const char *parameter_name = data.readCString(); 656 657 OMX_INDEXTYPE index; 658 status_t err = getExtensionIndex(node, parameter_name, &index); 659 660 reply->writeInt32(err); 661 662 if (err == OK) { 663 reply->writeInt32(index); 664 } 665 666 return OK; 667 } 668 669 case CREATE_RENDERER: 670 { 671 CHECK_INTERFACE(IOMX, data, reply); 672 673 sp<ISurface> isurface = 674 interface_cast<ISurface>(data.readStrongBinder()); 675 676 const char *componentName = data.readCString(); 677 678 OMX_COLOR_FORMATTYPE colorFormat = 679 static_cast<OMX_COLOR_FORMATTYPE>(data.readInt32()); 680 681 size_t encodedWidth = (size_t)data.readInt32(); 682 size_t encodedHeight = (size_t)data.readInt32(); 683 size_t displayWidth = (size_t)data.readInt32(); 684 size_t displayHeight = (size_t)data.readInt32(); 685 686 sp<IOMXRenderer> renderer = 687 createRenderer(isurface, componentName, colorFormat, 688 encodedWidth, encodedHeight, 689 displayWidth, displayHeight); 690 691 reply->writeStrongBinder(renderer->asBinder()); 692 693 return OK; 694 } 695 696 default: 697 return BBinder::onTransact(code, data, reply, flags); 698 } 699} 700 701//////////////////////////////////////////////////////////////////////////////// 702 703class BpOMXObserver : public BpInterface<IOMXObserver> { 704public: 705 BpOMXObserver(const sp<IBinder> &impl) 706 : BpInterface<IOMXObserver>(impl) { 707 } 708 709 virtual void onMessage(const omx_message &msg) { 710 Parcel data, reply; 711 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 712 data.write(&msg, sizeof(msg)); 713 714 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 715 } 716}; 717 718IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 719 720status_t BnOMXObserver::onTransact( 721 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 722 switch (code) { 723 case OBSERVER_ON_MSG: 724 { 725 CHECK_INTERFACE(IOMXObserver, data, reply); 726 727 omx_message msg; 728 data.read(&msg, sizeof(msg)); 729 730 // XXX Could use readInplace maybe? 731 onMessage(msg); 732 733 return NO_ERROR; 734 } 735 736 default: 737 return BBinder::onTransact(code, data, reply, flags); 738 } 739} 740 741//////////////////////////////////////////////////////////////////////////////// 742 743class BpOMXRenderer : public BpInterface<IOMXRenderer> { 744public: 745 BpOMXRenderer(const sp<IBinder> &impl) 746 : BpInterface<IOMXRenderer>(impl) { 747 } 748 749 virtual void render(IOMX::buffer_id buffer) { 750 Parcel data, reply; 751 data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor()); 752 data.writeIntPtr((intptr_t)buffer); 753 754 // NOTE: Do NOT make this a ONE_WAY call, it must be synchronous 755 // so that the caller knows when to recycle the buffer. 756 remote()->transact(RENDERER_RENDER, data, &reply); 757 } 758}; 759 760IMPLEMENT_META_INTERFACE(OMXRenderer, "android.hardware.IOMXRenderer"); 761 762status_t BnOMXRenderer::onTransact( 763 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 764 switch (code) { 765 case RENDERER_RENDER: 766 { 767 CHECK_INTERFACE(IOMXRenderer, data, reply); 768 769 IOMX::buffer_id buffer = (void*)data.readIntPtr(); 770 771 render(buffer); 772 773 return NO_ERROR; 774 } 775 776 default: 777 return BBinder::onTransact(code, data, reply, flags); 778 } 779} 780 781} // namespace android 782