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