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