1 /* 2 * Copyright (c) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "IOMX" 19 #include <utils/Log.h> 20 21 #include <binder/IMemory.h> 22 #include <binder/Parcel.h> 23 #include <media/IOMX.h> 24 #include <media/stagefright/foundation/ADebug.h> 25 26 namespace android { 27 28 enum { 29 CONNECT = IBinder::FIRST_CALL_TRANSACTION, 30 LIVES_LOCALLY, 31 LIST_NODES, 32 ALLOCATE_NODE, 33 FREE_NODE, 34 SEND_COMMAND, 35 GET_PARAMETER, 36 SET_PARAMETER, 37 GET_CONFIG, 38 SET_CONFIG, 39 GET_STATE, 40 ENABLE_GRAPHIC_BUFFERS, 41 USE_BUFFER, 42 USE_GRAPHIC_BUFFER, 43 CREATE_INPUT_SURFACE, 44 SIGNAL_END_OF_INPUT_STREAM, 45 STORE_META_DATA_IN_BUFFERS, 46 PREPARE_FOR_ADAPTIVE_PLAYBACK, 47 ALLOC_BUFFER, 48 ALLOC_BUFFER_WITH_BACKUP, 49 FREE_BUFFER, 50 FILL_BUFFER, 51 EMPTY_BUFFER, 52 GET_EXTENSION_INDEX, 53 OBSERVER_ON_MSG, 54 GET_GRAPHIC_BUFFER_USAGE, 55 SET_INTERNAL_OPTION, 56 UPDATE_GRAPHIC_BUFFER_IN_META, 57 }; 58 59 class BpOMX : public BpInterface<IOMX> { 60 public: 61 BpOMX(const sp<IBinder> &impl) 62 : BpInterface<IOMX>(impl) { 63 } 64 65 virtual bool livesLocally(node_id node, pid_t pid) { 66 Parcel data, reply; 67 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 68 data.writeIntPtr((intptr_t)node); 69 data.writeInt32(pid); 70 remote()->transact(LIVES_LOCALLY, data, &reply); 71 72 return reply.readInt32() != 0; 73 } 74 75 virtual status_t listNodes(List<ComponentInfo> *list) { 76 list->clear(); 77 78 Parcel data, reply; 79 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 80 remote()->transact(LIST_NODES, data, &reply); 81 82 int32_t n = reply.readInt32(); 83 for (int32_t i = 0; i < n; ++i) { 84 list->push_back(ComponentInfo()); 85 ComponentInfo &info = *--list->end(); 86 87 info.mName = reply.readString8(); 88 int32_t numRoles = reply.readInt32(); 89 for (int32_t j = 0; j < numRoles; ++j) { 90 info.mRoles.push_back(reply.readString8()); 91 } 92 } 93 94 return OK; 95 } 96 97 virtual status_t allocateNode( 98 const char *name, const sp<IOMXObserver> &observer, node_id *node) { 99 Parcel data, reply; 100 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 101 data.writeCString(name); 102 data.writeStrongBinder(observer->asBinder()); 103 remote()->transact(ALLOCATE_NODE, data, &reply); 104 105 status_t err = reply.readInt32(); 106 if (err == OK) { 107 *node = (void*)reply.readIntPtr(); 108 } else { 109 *node = 0; 110 } 111 112 return err; 113 } 114 115 virtual status_t freeNode(node_id node) { 116 Parcel data, reply; 117 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 118 data.writeIntPtr((intptr_t)node); 119 remote()->transact(FREE_NODE, data, &reply); 120 121 return reply.readInt32(); 122 } 123 124 virtual status_t sendCommand( 125 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { 126 Parcel data, reply; 127 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 128 data.writeIntPtr((intptr_t)node); 129 data.writeInt32(cmd); 130 data.writeInt32(param); 131 remote()->transact(SEND_COMMAND, data, &reply); 132 133 return reply.readInt32(); 134 } 135 136 virtual status_t getParameter( 137 node_id node, OMX_INDEXTYPE index, 138 void *params, size_t size) { 139 Parcel data, reply; 140 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 141 data.writeIntPtr((intptr_t)node); 142 data.writeInt32(index); 143 data.writeInt32(size); 144 data.write(params, size); 145 remote()->transact(GET_PARAMETER, data, &reply); 146 147 status_t err = reply.readInt32(); 148 if (err != OK) { 149 return err; 150 } 151 152 reply.read(params, size); 153 154 return OK; 155 } 156 157 virtual status_t setParameter( 158 node_id node, OMX_INDEXTYPE index, 159 const void *params, size_t size) { 160 Parcel data, reply; 161 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 162 data.writeIntPtr((intptr_t)node); 163 data.writeInt32(index); 164 data.writeInt32(size); 165 data.write(params, size); 166 remote()->transact(SET_PARAMETER, data, &reply); 167 168 return reply.readInt32(); 169 } 170 171 virtual status_t getConfig( 172 node_id node, OMX_INDEXTYPE index, 173 void *params, size_t size) { 174 Parcel data, reply; 175 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 176 data.writeIntPtr((intptr_t)node); 177 data.writeInt32(index); 178 data.writeInt32(size); 179 data.write(params, size); 180 remote()->transact(GET_CONFIG, data, &reply); 181 182 status_t err = reply.readInt32(); 183 if (err != OK) { 184 return err; 185 } 186 187 reply.read(params, size); 188 189 return OK; 190 } 191 192 virtual status_t setConfig( 193 node_id node, OMX_INDEXTYPE index, 194 const void *params, size_t size) { 195 Parcel data, reply; 196 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 197 data.writeIntPtr((intptr_t)node); 198 data.writeInt32(index); 199 data.writeInt32(size); 200 data.write(params, size); 201 remote()->transact(SET_CONFIG, data, &reply); 202 203 return reply.readInt32(); 204 } 205 206 virtual status_t getState( 207 node_id node, OMX_STATETYPE* state) { 208 Parcel data, reply; 209 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 210 data.writeIntPtr((intptr_t)node); 211 remote()->transact(GET_STATE, data, &reply); 212 213 *state = static_cast<OMX_STATETYPE>(reply.readInt32()); 214 return reply.readInt32(); 215 } 216 217 virtual status_t enableGraphicBuffers( 218 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 219 Parcel data, reply; 220 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 221 data.writeIntPtr((intptr_t)node); 222 data.writeInt32(port_index); 223 data.writeInt32((uint32_t)enable); 224 remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply); 225 226 status_t err = reply.readInt32(); 227 return err; 228 } 229 230 virtual status_t getGraphicBufferUsage( 231 node_id node, OMX_U32 port_index, OMX_U32* usage) { 232 Parcel data, reply; 233 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 234 data.writeIntPtr((intptr_t)node); 235 data.writeInt32(port_index); 236 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply); 237 238 status_t err = reply.readInt32(); 239 *usage = reply.readInt32(); 240 return err; 241 } 242 243 virtual status_t useBuffer( 244 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 245 buffer_id *buffer) { 246 Parcel data, reply; 247 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 248 data.writeIntPtr((intptr_t)node); 249 data.writeInt32(port_index); 250 data.writeStrongBinder(params->asBinder()); 251 remote()->transact(USE_BUFFER, data, &reply); 252 253 status_t err = reply.readInt32(); 254 if (err != OK) { 255 *buffer = 0; 256 257 return err; 258 } 259 260 *buffer = (void*)reply.readIntPtr(); 261 262 return err; 263 } 264 265 266 virtual status_t useGraphicBuffer( 267 node_id node, OMX_U32 port_index, 268 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { 269 Parcel data, reply; 270 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 271 data.writeIntPtr((intptr_t)node); 272 data.writeInt32(port_index); 273 data.write(*graphicBuffer); 274 remote()->transact(USE_GRAPHIC_BUFFER, data, &reply); 275 276 status_t err = reply.readInt32(); 277 if (err != OK) { 278 *buffer = 0; 279 280 return err; 281 } 282 283 *buffer = (void*)reply.readIntPtr(); 284 285 return err; 286 } 287 288 virtual status_t updateGraphicBufferInMeta( 289 node_id node, OMX_U32 port_index, 290 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { 291 Parcel data, reply; 292 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 293 data.writeIntPtr((intptr_t)node); 294 data.writeInt32(port_index); 295 data.write(*graphicBuffer); 296 data.writeIntPtr((intptr_t)buffer); 297 remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply); 298 299 status_t err = reply.readInt32(); 300 return err; 301 } 302 303 virtual status_t createInputSurface( 304 node_id node, OMX_U32 port_index, 305 sp<IGraphicBufferProducer> *bufferProducer) { 306 Parcel data, reply; 307 status_t err; 308 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 309 data.writeIntPtr((intptr_t)node); 310 data.writeInt32(port_index); 311 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply); 312 if (err != OK) { 313 ALOGW("binder transaction failed: %d", err); 314 return err; 315 } 316 317 err = reply.readInt32(); 318 if (err != OK) { 319 return err; 320 } 321 322 *bufferProducer = IGraphicBufferProducer::asInterface( 323 reply.readStrongBinder()); 324 325 return err; 326 } 327 328 virtual status_t signalEndOfInputStream(node_id node) { 329 Parcel data, reply; 330 status_t err; 331 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 332 data.writeIntPtr((intptr_t)node); 333 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply); 334 if (err != OK) { 335 ALOGW("binder transaction failed: %d", err); 336 return err; 337 } 338 339 return reply.readInt32(); 340 } 341 342 virtual status_t storeMetaDataInBuffers( 343 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 344 Parcel data, reply; 345 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 346 data.writeIntPtr((intptr_t)node); 347 data.writeInt32(port_index); 348 data.writeInt32((uint32_t)enable); 349 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); 350 351 status_t err = reply.readInt32(); 352 return err; 353 } 354 355 virtual status_t prepareForAdaptivePlayback( 356 node_id node, OMX_U32 port_index, OMX_BOOL enable, 357 OMX_U32 max_width, OMX_U32 max_height) { 358 Parcel data, reply; 359 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 360 data.writeIntPtr((intptr_t)node); 361 data.writeInt32(port_index); 362 data.writeInt32((int32_t)enable); 363 data.writeInt32(max_width); 364 data.writeInt32(max_height); 365 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply); 366 367 status_t err = reply.readInt32(); 368 return err; 369 } 370 371 virtual status_t allocateBuffer( 372 node_id node, OMX_U32 port_index, size_t size, 373 buffer_id *buffer, void **buffer_data) { 374 Parcel data, reply; 375 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 376 data.writeIntPtr((intptr_t)node); 377 data.writeInt32(port_index); 378 data.writeInt32(size); 379 remote()->transact(ALLOC_BUFFER, data, &reply); 380 381 status_t err = reply.readInt32(); 382 if (err != OK) { 383 *buffer = 0; 384 385 return err; 386 } 387 388 *buffer = (void *)reply.readIntPtr(); 389 *buffer_data = (void *)reply.readIntPtr(); 390 391 return err; 392 } 393 394 virtual status_t allocateBufferWithBackup( 395 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 396 buffer_id *buffer) { 397 Parcel data, reply; 398 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 399 data.writeIntPtr((intptr_t)node); 400 data.writeInt32(port_index); 401 data.writeStrongBinder(params->asBinder()); 402 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply); 403 404 status_t err = reply.readInt32(); 405 if (err != OK) { 406 *buffer = 0; 407 408 return err; 409 } 410 411 *buffer = (void*)reply.readIntPtr(); 412 413 return err; 414 } 415 416 virtual status_t freeBuffer( 417 node_id node, OMX_U32 port_index, buffer_id buffer) { 418 Parcel data, reply; 419 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 420 data.writeIntPtr((intptr_t)node); 421 data.writeInt32(port_index); 422 data.writeIntPtr((intptr_t)buffer); 423 remote()->transact(FREE_BUFFER, data, &reply); 424 425 return reply.readInt32(); 426 } 427 428 virtual status_t fillBuffer(node_id node, buffer_id buffer) { 429 Parcel data, reply; 430 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 431 data.writeIntPtr((intptr_t)node); 432 data.writeIntPtr((intptr_t)buffer); 433 remote()->transact(FILL_BUFFER, data, &reply); 434 435 return reply.readInt32(); 436 } 437 438 virtual status_t emptyBuffer( 439 node_id node, 440 buffer_id buffer, 441 OMX_U32 range_offset, OMX_U32 range_length, 442 OMX_U32 flags, OMX_TICKS timestamp) { 443 Parcel data, reply; 444 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 445 data.writeIntPtr((intptr_t)node); 446 data.writeIntPtr((intptr_t)buffer); 447 data.writeInt32(range_offset); 448 data.writeInt32(range_length); 449 data.writeInt32(flags); 450 data.writeInt64(timestamp); 451 remote()->transact(EMPTY_BUFFER, data, &reply); 452 453 return reply.readInt32(); 454 } 455 456 virtual status_t getExtensionIndex( 457 node_id node, 458 const char *parameter_name, 459 OMX_INDEXTYPE *index) { 460 Parcel data, reply; 461 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 462 data.writeIntPtr((intptr_t)node); 463 data.writeCString(parameter_name); 464 465 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 466 467 status_t err = reply.readInt32(); 468 if (err == OK) { 469 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 470 } else { 471 *index = OMX_IndexComponentStartUnused; 472 } 473 474 return err; 475 } 476 477 virtual status_t setInternalOption( 478 node_id node, 479 OMX_U32 port_index, 480 InternalOptionType type, 481 const void *optionData, 482 size_t size) { 483 Parcel data, reply; 484 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 485 data.writeIntPtr((intptr_t)node); 486 data.writeInt32(port_index); 487 data.writeInt32(size); 488 data.write(optionData, size); 489 data.writeInt32(type); 490 remote()->transact(SET_INTERNAL_OPTION, data, &reply); 491 492 return reply.readInt32(); 493 } 494 }; 495 496 IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); 497 498 //////////////////////////////////////////////////////////////////////////////// 499 500 #define CHECK_OMX_INTERFACE(interface, data, reply) \ 501 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 502 ALOGW("Call incorrectly routed to " #interface); \ 503 return PERMISSION_DENIED; \ 504 } } while (0) 505 506 status_t BnOMX::onTransact( 507 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 508 switch (code) { 509 case LIVES_LOCALLY: 510 { 511 CHECK_OMX_INTERFACE(IOMX, data, reply); 512 node_id node = (void *)data.readIntPtr(); 513 pid_t pid = (pid_t)data.readInt32(); 514 reply->writeInt32(livesLocally(node, pid)); 515 516 return OK; 517 } 518 519 case LIST_NODES: 520 { 521 CHECK_OMX_INTERFACE(IOMX, data, reply); 522 523 List<ComponentInfo> list; 524 listNodes(&list); 525 526 reply->writeInt32(list.size()); 527 for (List<ComponentInfo>::iterator it = list.begin(); 528 it != list.end(); ++it) { 529 ComponentInfo &cur = *it; 530 531 reply->writeString8(cur.mName); 532 reply->writeInt32(cur.mRoles.size()); 533 for (List<String8>::iterator role_it = cur.mRoles.begin(); 534 role_it != cur.mRoles.end(); ++role_it) { 535 reply->writeString8(*role_it); 536 } 537 } 538 539 return NO_ERROR; 540 } 541 542 case ALLOCATE_NODE: 543 { 544 CHECK_OMX_INTERFACE(IOMX, data, reply); 545 546 const char *name = data.readCString(); 547 548 sp<IOMXObserver> observer = 549 interface_cast<IOMXObserver>(data.readStrongBinder()); 550 551 node_id node; 552 553 status_t err = allocateNode(name, observer, &node); 554 reply->writeInt32(err); 555 if (err == OK) { 556 reply->writeIntPtr((intptr_t)node); 557 } 558 559 return NO_ERROR; 560 } 561 562 case FREE_NODE: 563 { 564 CHECK_OMX_INTERFACE(IOMX, data, reply); 565 566 node_id node = (void*)data.readIntPtr(); 567 568 reply->writeInt32(freeNode(node)); 569 570 return NO_ERROR; 571 } 572 573 case SEND_COMMAND: 574 { 575 CHECK_OMX_INTERFACE(IOMX, data, reply); 576 577 node_id node = (void*)data.readIntPtr(); 578 579 OMX_COMMANDTYPE cmd = 580 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 581 582 OMX_S32 param = data.readInt32(); 583 reply->writeInt32(sendCommand(node, cmd, param)); 584 585 return NO_ERROR; 586 } 587 588 case GET_PARAMETER: 589 case SET_PARAMETER: 590 case GET_CONFIG: 591 case SET_CONFIG: 592 case SET_INTERNAL_OPTION: 593 { 594 CHECK_OMX_INTERFACE(IOMX, data, reply); 595 596 node_id node = (void*)data.readIntPtr(); 597 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 598 599 size_t size = data.readInt32(); 600 601 void *params = malloc(size); 602 data.read(params, size); 603 604 status_t err; 605 switch (code) { 606 case GET_PARAMETER: 607 err = getParameter(node, index, params, size); 608 break; 609 case SET_PARAMETER: 610 err = setParameter(node, index, params, size); 611 break; 612 case GET_CONFIG: 613 err = getConfig(node, index, params, size); 614 break; 615 case SET_CONFIG: 616 err = setConfig(node, index, params, size); 617 break; 618 case SET_INTERNAL_OPTION: 619 { 620 InternalOptionType type = 621 (InternalOptionType)data.readInt32(); 622 623 err = setInternalOption(node, index, type, params, size); 624 break; 625 } 626 627 default: 628 TRESPASS(); 629 } 630 631 reply->writeInt32(err); 632 633 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 634 reply->write(params, size); 635 } 636 637 free(params); 638 params = NULL; 639 640 return NO_ERROR; 641 } 642 643 case GET_STATE: 644 { 645 CHECK_OMX_INTERFACE(IOMX, data, reply); 646 647 node_id node = (void*)data.readIntPtr(); 648 OMX_STATETYPE state = OMX_StateInvalid; 649 650 status_t err = getState(node, &state); 651 reply->writeInt32(state); 652 reply->writeInt32(err); 653 654 return NO_ERROR; 655 } 656 657 case ENABLE_GRAPHIC_BUFFERS: 658 { 659 CHECK_OMX_INTERFACE(IOMX, data, reply); 660 661 node_id node = (void*)data.readIntPtr(); 662 OMX_U32 port_index = data.readInt32(); 663 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 664 665 status_t err = enableGraphicBuffers(node, port_index, enable); 666 reply->writeInt32(err); 667 668 return NO_ERROR; 669 } 670 671 case GET_GRAPHIC_BUFFER_USAGE: 672 { 673 CHECK_OMX_INTERFACE(IOMX, data, reply); 674 675 node_id node = (void*)data.readIntPtr(); 676 OMX_U32 port_index = data.readInt32(); 677 678 OMX_U32 usage = 0; 679 status_t err = getGraphicBufferUsage(node, port_index, &usage); 680 reply->writeInt32(err); 681 reply->writeInt32(usage); 682 683 return NO_ERROR; 684 } 685 686 case USE_BUFFER: 687 { 688 CHECK_OMX_INTERFACE(IOMX, data, reply); 689 690 node_id node = (void*)data.readIntPtr(); 691 OMX_U32 port_index = data.readInt32(); 692 sp<IMemory> params = 693 interface_cast<IMemory>(data.readStrongBinder()); 694 695 buffer_id buffer; 696 status_t err = useBuffer(node, port_index, params, &buffer); 697 reply->writeInt32(err); 698 699 if (err == OK) { 700 reply->writeIntPtr((intptr_t)buffer); 701 } 702 703 return NO_ERROR; 704 } 705 706 case USE_GRAPHIC_BUFFER: 707 { 708 CHECK_OMX_INTERFACE(IOMX, data, reply); 709 710 node_id node = (void*)data.readIntPtr(); 711 OMX_U32 port_index = data.readInt32(); 712 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 713 data.read(*graphicBuffer); 714 715 buffer_id buffer; 716 status_t err = useGraphicBuffer( 717 node, port_index, graphicBuffer, &buffer); 718 reply->writeInt32(err); 719 720 if (err == OK) { 721 reply->writeIntPtr((intptr_t)buffer); 722 } 723 724 return NO_ERROR; 725 } 726 727 case UPDATE_GRAPHIC_BUFFER_IN_META: 728 { 729 CHECK_OMX_INTERFACE(IOMX, data, reply); 730 731 node_id node = (void*)data.readIntPtr(); 732 OMX_U32 port_index = data.readInt32(); 733 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 734 data.read(*graphicBuffer); 735 buffer_id buffer = (void*)data.readIntPtr(); 736 737 status_t err = updateGraphicBufferInMeta( 738 node, port_index, graphicBuffer, buffer); 739 reply->writeInt32(err); 740 741 return NO_ERROR; 742 } 743 744 case CREATE_INPUT_SURFACE: 745 { 746 CHECK_OMX_INTERFACE(IOMX, data, reply); 747 748 node_id node = (void*)data.readIntPtr(); 749 OMX_U32 port_index = data.readInt32(); 750 751 sp<IGraphicBufferProducer> bufferProducer; 752 status_t err = createInputSurface(node, port_index, 753 &bufferProducer); 754 755 reply->writeInt32(err); 756 757 if (err == OK) { 758 reply->writeStrongBinder(bufferProducer->asBinder()); 759 } 760 761 return NO_ERROR; 762 } 763 764 case SIGNAL_END_OF_INPUT_STREAM: 765 { 766 CHECK_OMX_INTERFACE(IOMX, data, reply); 767 768 node_id node = (void*)data.readIntPtr(); 769 770 status_t err = signalEndOfInputStream(node); 771 reply->writeInt32(err); 772 773 return NO_ERROR; 774 } 775 776 case STORE_META_DATA_IN_BUFFERS: 777 { 778 CHECK_OMX_INTERFACE(IOMX, data, reply); 779 780 node_id node = (void*)data.readIntPtr(); 781 OMX_U32 port_index = data.readInt32(); 782 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 783 784 status_t err = storeMetaDataInBuffers(node, port_index, enable); 785 reply->writeInt32(err); 786 787 return NO_ERROR; 788 } 789 790 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 791 { 792 CHECK_OMX_INTERFACE(IOMX, data, reply); 793 794 node_id node = (void*)data.readIntPtr(); 795 OMX_U32 port_index = data.readInt32(); 796 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 797 OMX_U32 max_width = data.readInt32(); 798 OMX_U32 max_height = data.readInt32(); 799 800 status_t err = prepareForAdaptivePlayback( 801 node, port_index, enable, max_width, max_height); 802 reply->writeInt32(err); 803 804 return NO_ERROR; 805 } 806 807 case ALLOC_BUFFER: 808 { 809 CHECK_OMX_INTERFACE(IOMX, data, reply); 810 811 node_id node = (void*)data.readIntPtr(); 812 OMX_U32 port_index = data.readInt32(); 813 size_t size = data.readInt32(); 814 815 buffer_id buffer; 816 void *buffer_data; 817 status_t err = allocateBuffer( 818 node, port_index, size, &buffer, &buffer_data); 819 reply->writeInt32(err); 820 821 if (err == OK) { 822 reply->writeIntPtr((intptr_t)buffer); 823 reply->writeIntPtr((intptr_t)buffer_data); 824 } 825 826 return NO_ERROR; 827 } 828 829 case ALLOC_BUFFER_WITH_BACKUP: 830 { 831 CHECK_OMX_INTERFACE(IOMX, data, reply); 832 833 node_id node = (void*)data.readIntPtr(); 834 OMX_U32 port_index = data.readInt32(); 835 sp<IMemory> params = 836 interface_cast<IMemory>(data.readStrongBinder()); 837 838 buffer_id buffer; 839 status_t err = allocateBufferWithBackup( 840 node, port_index, params, &buffer); 841 842 reply->writeInt32(err); 843 844 if (err == OK) { 845 reply->writeIntPtr((intptr_t)buffer); 846 } 847 848 return NO_ERROR; 849 } 850 851 case FREE_BUFFER: 852 { 853 CHECK_OMX_INTERFACE(IOMX, data, reply); 854 855 node_id node = (void*)data.readIntPtr(); 856 OMX_U32 port_index = data.readInt32(); 857 buffer_id buffer = (void*)data.readIntPtr(); 858 reply->writeInt32(freeBuffer(node, port_index, buffer)); 859 860 return NO_ERROR; 861 } 862 863 case FILL_BUFFER: 864 { 865 CHECK_OMX_INTERFACE(IOMX, data, reply); 866 867 node_id node = (void*)data.readIntPtr(); 868 buffer_id buffer = (void*)data.readIntPtr(); 869 reply->writeInt32(fillBuffer(node, buffer)); 870 871 return NO_ERROR; 872 } 873 874 case EMPTY_BUFFER: 875 { 876 CHECK_OMX_INTERFACE(IOMX, data, reply); 877 878 node_id node = (void*)data.readIntPtr(); 879 buffer_id buffer = (void*)data.readIntPtr(); 880 OMX_U32 range_offset = data.readInt32(); 881 OMX_U32 range_length = data.readInt32(); 882 OMX_U32 flags = data.readInt32(); 883 OMX_TICKS timestamp = data.readInt64(); 884 885 reply->writeInt32( 886 emptyBuffer( 887 node, buffer, range_offset, range_length, 888 flags, timestamp)); 889 890 return NO_ERROR; 891 } 892 893 case GET_EXTENSION_INDEX: 894 { 895 CHECK_OMX_INTERFACE(IOMX, data, reply); 896 897 node_id node = (void*)data.readIntPtr(); 898 const char *parameter_name = data.readCString(); 899 900 OMX_INDEXTYPE index; 901 status_t err = getExtensionIndex(node, parameter_name, &index); 902 903 reply->writeInt32(err); 904 905 if (err == OK) { 906 reply->writeInt32(index); 907 } 908 909 return OK; 910 } 911 912 default: 913 return BBinder::onTransact(code, data, reply, flags); 914 } 915 } 916 917 //////////////////////////////////////////////////////////////////////////////// 918 919 class BpOMXObserver : public BpInterface<IOMXObserver> { 920 public: 921 BpOMXObserver(const sp<IBinder> &impl) 922 : BpInterface<IOMXObserver>(impl) { 923 } 924 925 virtual void onMessage(const omx_message &msg) { 926 Parcel data, reply; 927 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 928 data.write(&msg, sizeof(msg)); 929 930 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 931 } 932 }; 933 934 IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 935 936 status_t BnOMXObserver::onTransact( 937 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 938 switch (code) { 939 case OBSERVER_ON_MSG: 940 { 941 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 942 943 omx_message msg; 944 data.read(&msg, sizeof(msg)); 945 946 // XXX Could use readInplace maybe? 947 onMessage(msg); 948 949 return NO_ERROR; 950 } 951 952 default: 953 return BBinder::onTransact(code, data, reply, flags); 954 } 955 } 956 957 } // namespace android 958