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 CREATE_PERSISTENT_INPUT_SURFACE, 45 SET_INPUT_SURFACE, 46 SIGNAL_END_OF_INPUT_STREAM, 47 STORE_META_DATA_IN_BUFFERS, 48 PREPARE_FOR_ADAPTIVE_PLAYBACK, 49 ALLOC_BUFFER, 50 ALLOC_BUFFER_WITH_BACKUP, 51 FREE_BUFFER, 52 FILL_BUFFER, 53 EMPTY_BUFFER, 54 GET_EXTENSION_INDEX, 55 OBSERVER_ON_MSG, 56 GET_GRAPHIC_BUFFER_USAGE, 57 SET_INTERNAL_OPTION, 58 UPDATE_GRAPHIC_BUFFER_IN_META, 59 CONFIGURE_VIDEO_TUNNEL_MODE, 60 }; 61 62 class BpOMX : public BpInterface<IOMX> { 63 public: 64 BpOMX(const sp<IBinder> &impl) 65 : BpInterface<IOMX>(impl) { 66 } 67 68 virtual bool livesLocally(node_id node, pid_t pid) { 69 Parcel data, reply; 70 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 71 data.writeInt32((int32_t)node); 72 data.writeInt32(pid); 73 remote()->transact(LIVES_LOCALLY, data, &reply); 74 75 return reply.readInt32() != 0; 76 } 77 78 virtual status_t listNodes(List<ComponentInfo> *list) { 79 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) { 87 list->push_back(ComponentInfo()); 88 ComponentInfo &info = *--list->end(); 89 90 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 } 95 } 96 97 return OK; 98 } 99 100 virtual status_t allocateNode( 101 const char *name, const sp<IOMXObserver> &observer, node_id *node) { 102 Parcel data, reply; 103 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 104 data.writeCString(name); 105 data.writeStrongBinder(IInterface::asBinder(observer)); 106 remote()->transact(ALLOCATE_NODE, data, &reply); 107 108 status_t err = reply.readInt32(); 109 if (err == OK) { 110 *node = (node_id)reply.readInt32(); 111 } else { 112 *node = 0; 113 } 114 115 return err; 116 } 117 118 virtual status_t freeNode(node_id node) { 119 Parcel data, reply; 120 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 121 data.writeInt32((int32_t)node); 122 remote()->transact(FREE_NODE, data, &reply); 123 124 return reply.readInt32(); 125 } 126 127 virtual status_t sendCommand( 128 node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) { 129 Parcel data, reply; 130 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 131 data.writeInt32((int32_t)node); 132 data.writeInt32(cmd); 133 data.writeInt32(param); 134 remote()->transact(SEND_COMMAND, data, &reply); 135 136 return reply.readInt32(); 137 } 138 139 virtual status_t getParameter( 140 node_id node, OMX_INDEXTYPE index, 141 void *params, size_t size) { 142 Parcel data, reply; 143 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 144 data.writeInt32((int32_t)node); 145 data.writeInt32(index); 146 data.writeInt64(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 160 virtual status_t setParameter( 161 node_id node, OMX_INDEXTYPE index, 162 const void *params, size_t size) { 163 Parcel data, reply; 164 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 165 data.writeInt32((int32_t)node); 166 data.writeInt32(index); 167 data.writeInt64(size); 168 data.write(params, size); 169 remote()->transact(SET_PARAMETER, data, &reply); 170 171 return reply.readInt32(); 172 } 173 174 virtual status_t getConfig( 175 node_id node, OMX_INDEXTYPE index, 176 void *params, size_t size) { 177 Parcel data, reply; 178 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 179 data.writeInt32((int32_t)node); 180 data.writeInt32(index); 181 data.writeInt64(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 195 virtual status_t setConfig( 196 node_id node, OMX_INDEXTYPE index, 197 const void *params, size_t size) { 198 Parcel data, reply; 199 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 200 data.writeInt32((int32_t)node); 201 data.writeInt32(index); 202 data.writeInt64(size); 203 data.write(params, size); 204 remote()->transact(SET_CONFIG, data, &reply); 205 206 return reply.readInt32(); 207 } 208 209 virtual status_t getState( 210 node_id node, OMX_STATETYPE* state) { 211 Parcel data, reply; 212 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 213 data.writeInt32((int32_t)node); 214 remote()->transact(GET_STATE, data, &reply); 215 216 *state = static_cast<OMX_STATETYPE>(reply.readInt32()); 217 return reply.readInt32(); 218 } 219 220 virtual status_t enableGraphicBuffers( 221 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 222 Parcel data, reply; 223 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 224 data.writeInt32((int32_t)node); 225 data.writeInt32(port_index); 226 data.writeInt32((uint32_t)enable); 227 remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply); 228 229 status_t err = reply.readInt32(); 230 return err; 231 } 232 233 virtual status_t getGraphicBufferUsage( 234 node_id node, OMX_U32 port_index, OMX_U32* usage) { 235 Parcel data, reply; 236 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 237 data.writeInt32((int32_t)node); 238 data.writeInt32(port_index); 239 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply); 240 241 status_t err = reply.readInt32(); 242 *usage = reply.readInt32(); 243 return err; 244 } 245 246 virtual status_t useBuffer( 247 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 248 buffer_id *buffer, OMX_U32 allottedSize) { 249 Parcel data, reply; 250 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 251 data.writeInt32((int32_t)node); 252 data.writeInt32(port_index); 253 data.writeStrongBinder(IInterface::asBinder(params)); 254 data.writeInt32(allottedSize); 255 remote()->transact(USE_BUFFER, data, &reply); 256 257 status_t err = reply.readInt32(); 258 if (err != OK) { 259 *buffer = 0; 260 261 return err; 262 } 263 264 *buffer = (buffer_id)reply.readInt32(); 265 266 return err; 267 } 268 269 270 virtual status_t useGraphicBuffer( 271 node_id node, OMX_U32 port_index, 272 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { 273 Parcel data, reply; 274 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 275 data.writeInt32((int32_t)node); 276 data.writeInt32(port_index); 277 data.write(*graphicBuffer); 278 remote()->transact(USE_GRAPHIC_BUFFER, data, &reply); 279 280 status_t err = reply.readInt32(); 281 if (err != OK) { 282 *buffer = 0; 283 284 return err; 285 } 286 287 *buffer = (buffer_id)reply.readInt32(); 288 289 return err; 290 } 291 292 virtual status_t updateGraphicBufferInMeta( 293 node_id node, OMX_U32 port_index, 294 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { 295 Parcel data, reply; 296 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 297 data.writeInt32((int32_t)node); 298 data.writeInt32(port_index); 299 data.write(*graphicBuffer); 300 data.writeInt32((int32_t)buffer); 301 remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply); 302 303 status_t err = reply.readInt32(); 304 return err; 305 } 306 307 virtual status_t createInputSurface( 308 node_id node, OMX_U32 port_index, 309 sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) { 310 Parcel data, reply; 311 status_t err; 312 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 313 data.writeInt32((int32_t)node); 314 data.writeInt32(port_index); 315 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply); 316 if (err != OK) { 317 ALOGW("binder transaction failed: %d", err); 318 return err; 319 } 320 321 // read type even if createInputSurface failed 322 int negotiatedType = reply.readInt32(); 323 if (type != NULL) { 324 *type = (MetadataBufferType)negotiatedType; 325 } 326 327 err = reply.readInt32(); 328 if (err != OK) { 329 return err; 330 } 331 332 *bufferProducer = IGraphicBufferProducer::asInterface( 333 reply.readStrongBinder()); 334 335 return err; 336 } 337 338 virtual status_t createPersistentInputSurface( 339 sp<IGraphicBufferProducer> *bufferProducer, 340 sp<IGraphicBufferConsumer> *bufferConsumer) { 341 Parcel data, reply; 342 status_t err; 343 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 344 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply); 345 if (err != OK) { 346 ALOGW("binder transaction failed: %d", err); 347 return err; 348 } 349 350 err = reply.readInt32(); 351 if (err != OK) { 352 return err; 353 } 354 355 *bufferProducer = IGraphicBufferProducer::asInterface( 356 reply.readStrongBinder()); 357 *bufferConsumer = IGraphicBufferConsumer::asInterface( 358 reply.readStrongBinder()); 359 360 return err; 361 } 362 363 virtual status_t setInputSurface( 364 node_id node, OMX_U32 port_index, 365 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) { 366 Parcel data, reply; 367 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 368 status_t err; 369 data.writeInt32((int32_t)node); 370 data.writeInt32(port_index); 371 data.writeStrongBinder(IInterface::asBinder(bufferConsumer)); 372 373 err = remote()->transact(SET_INPUT_SURFACE, data, &reply); 374 375 if (err != OK) { 376 ALOGW("binder transaction failed: %d", err); 377 return err; 378 } 379 380 // read type even if setInputSurface failed 381 int negotiatedType = reply.readInt32(); 382 if (type != NULL) { 383 *type = (MetadataBufferType)negotiatedType; 384 } 385 386 return reply.readInt32(); 387 } 388 389 virtual status_t signalEndOfInputStream(node_id node) { 390 Parcel data, reply; 391 status_t err; 392 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 393 data.writeInt32((int32_t)node); 394 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply); 395 if (err != OK) { 396 ALOGW("binder transaction failed: %d", err); 397 return err; 398 } 399 400 return reply.readInt32(); 401 } 402 403 virtual status_t storeMetaDataInBuffers( 404 node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) { 405 Parcel data, reply; 406 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 407 data.writeInt32((int32_t)node); 408 data.writeInt32(port_index); 409 data.writeInt32((uint32_t)enable); 410 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); 411 412 // read type even storeMetaDataInBuffers failed 413 int negotiatedType = reply.readInt32(); 414 if (type != NULL) { 415 *type = (MetadataBufferType)negotiatedType; 416 } 417 418 return reply.readInt32(); 419 } 420 421 virtual status_t prepareForAdaptivePlayback( 422 node_id node, OMX_U32 port_index, OMX_BOOL enable, 423 OMX_U32 max_width, OMX_U32 max_height) { 424 Parcel data, reply; 425 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 426 data.writeInt32((int32_t)node); 427 data.writeInt32(port_index); 428 data.writeInt32((int32_t)enable); 429 data.writeInt32(max_width); 430 data.writeInt32(max_height); 431 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply); 432 433 status_t err = reply.readInt32(); 434 return err; 435 } 436 437 virtual status_t configureVideoTunnelMode( 438 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, 439 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) { 440 Parcel data, reply; 441 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 442 data.writeInt32((int32_t)node); 443 data.writeInt32(portIndex); 444 data.writeInt32((int32_t)tunneled); 445 data.writeInt32(audioHwSync); 446 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply); 447 448 status_t err = reply.readInt32(); 449 if (sidebandHandle) { 450 *sidebandHandle = (native_handle_t *)reply.readNativeHandle(); 451 } 452 return err; 453 } 454 455 456 virtual status_t allocateBuffer( 457 node_id node, OMX_U32 port_index, size_t size, 458 buffer_id *buffer, void **buffer_data) { 459 Parcel data, reply; 460 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 461 data.writeInt32((int32_t)node); 462 data.writeInt32(port_index); 463 data.writeInt64(size); 464 remote()->transact(ALLOC_BUFFER, data, &reply); 465 466 status_t err = reply.readInt32(); 467 if (err != OK) { 468 *buffer = 0; 469 470 return err; 471 } 472 473 *buffer = (buffer_id)reply.readInt32(); 474 *buffer_data = (void *)reply.readInt64(); 475 476 return err; 477 } 478 479 virtual status_t allocateBufferWithBackup( 480 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 481 buffer_id *buffer, OMX_U32 allottedSize) { 482 Parcel data, reply; 483 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 484 data.writeInt32((int32_t)node); 485 data.writeInt32(port_index); 486 data.writeStrongBinder(IInterface::asBinder(params)); 487 data.writeInt32(allottedSize); 488 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply); 489 490 status_t err = reply.readInt32(); 491 if (err != OK) { 492 *buffer = 0; 493 494 return err; 495 } 496 497 *buffer = (buffer_id)reply.readInt32(); 498 499 return err; 500 } 501 502 virtual status_t freeBuffer( 503 node_id node, OMX_U32 port_index, buffer_id buffer) { 504 Parcel data, reply; 505 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 506 data.writeInt32((int32_t)node); 507 data.writeInt32(port_index); 508 data.writeInt32((int32_t)buffer); 509 remote()->transact(FREE_BUFFER, data, &reply); 510 511 return reply.readInt32(); 512 } 513 514 virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) { 515 Parcel data, reply; 516 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 517 data.writeInt32((int32_t)node); 518 data.writeInt32((int32_t)buffer); 519 data.writeInt32(fenceFd >= 0); 520 if (fenceFd >= 0) { 521 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 522 } 523 remote()->transact(FILL_BUFFER, data, &reply); 524 525 return reply.readInt32(); 526 } 527 528 virtual status_t emptyBuffer( 529 node_id node, 530 buffer_id buffer, 531 OMX_U32 range_offset, OMX_U32 range_length, 532 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 533 Parcel data, reply; 534 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 535 data.writeInt32((int32_t)node); 536 data.writeInt32((int32_t)buffer); 537 data.writeInt32(range_offset); 538 data.writeInt32(range_length); 539 data.writeInt32(flags); 540 data.writeInt64(timestamp); 541 data.writeInt32(fenceFd >= 0); 542 if (fenceFd >= 0) { 543 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 544 } 545 remote()->transact(EMPTY_BUFFER, data, &reply); 546 547 return reply.readInt32(); 548 } 549 550 virtual status_t getExtensionIndex( 551 node_id node, 552 const char *parameter_name, 553 OMX_INDEXTYPE *index) { 554 Parcel data, reply; 555 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 556 data.writeInt32((int32_t)node); 557 data.writeCString(parameter_name); 558 559 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 560 561 status_t err = reply.readInt32(); 562 if (err == OK) { 563 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 564 } else { 565 *index = OMX_IndexComponentStartUnused; 566 } 567 568 return err; 569 } 570 571 virtual status_t setInternalOption( 572 node_id node, 573 OMX_U32 port_index, 574 InternalOptionType type, 575 const void *optionData, 576 size_t size) { 577 Parcel data, reply; 578 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 579 data.writeInt32((int32_t)node); 580 data.writeInt32(port_index); 581 data.writeInt64(size); 582 data.write(optionData, size); 583 data.writeInt32(type); 584 remote()->transact(SET_INTERNAL_OPTION, data, &reply); 585 586 return reply.readInt32(); 587 } 588 }; 589 590 IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); 591 592 //////////////////////////////////////////////////////////////////////////////// 593 594 #define CHECK_OMX_INTERFACE(interface, data, reply) \ 595 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 596 ALOGW("Call incorrectly routed to " #interface); \ 597 return PERMISSION_DENIED; \ 598 } } while (0) 599 600 status_t BnOMX::onTransact( 601 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 602 switch (code) { 603 case LIVES_LOCALLY: 604 { 605 CHECK_OMX_INTERFACE(IOMX, data, reply); 606 node_id node = (node_id)data.readInt32(); 607 pid_t pid = (pid_t)data.readInt32(); 608 reply->writeInt32(livesLocally(node, pid)); 609 610 return OK; 611 } 612 613 case LIST_NODES: 614 { 615 CHECK_OMX_INTERFACE(IOMX, data, reply); 616 617 List<ComponentInfo> list; 618 listNodes(&list); 619 620 reply->writeInt32(list.size()); 621 for (List<ComponentInfo>::iterator it = list.begin(); 622 it != list.end(); ++it) { 623 ComponentInfo &cur = *it; 624 625 reply->writeString8(cur.mName); 626 reply->writeInt32(cur.mRoles.size()); 627 for (List<String8>::iterator role_it = cur.mRoles.begin(); 628 role_it != cur.mRoles.end(); ++role_it) { 629 reply->writeString8(*role_it); 630 } 631 } 632 633 return NO_ERROR; 634 } 635 636 case ALLOCATE_NODE: 637 { 638 CHECK_OMX_INTERFACE(IOMX, data, reply); 639 640 const char *name = data.readCString(); 641 642 sp<IOMXObserver> observer = 643 interface_cast<IOMXObserver>(data.readStrongBinder()); 644 645 node_id node; 646 647 status_t err = allocateNode(name, observer, &node); 648 reply->writeInt32(err); 649 if (err == OK) { 650 reply->writeInt32((int32_t)node); 651 } 652 653 return NO_ERROR; 654 } 655 656 case FREE_NODE: 657 { 658 CHECK_OMX_INTERFACE(IOMX, data, reply); 659 660 node_id node = (node_id)data.readInt32(); 661 662 reply->writeInt32(freeNode(node)); 663 664 return NO_ERROR; 665 } 666 667 case SEND_COMMAND: 668 { 669 CHECK_OMX_INTERFACE(IOMX, data, reply); 670 671 node_id node = (node_id)data.readInt32(); 672 673 OMX_COMMANDTYPE cmd = 674 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 675 676 OMX_S32 param = data.readInt32(); 677 reply->writeInt32(sendCommand(node, cmd, param)); 678 679 return NO_ERROR; 680 } 681 682 case GET_PARAMETER: 683 case SET_PARAMETER: 684 case GET_CONFIG: 685 case SET_CONFIG: 686 case SET_INTERNAL_OPTION: 687 { 688 CHECK_OMX_INTERFACE(IOMX, data, reply); 689 690 node_id node = (node_id)data.readInt32(); 691 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 692 693 size_t size = data.readInt64(); 694 695 void *params = malloc(size); 696 data.read(params, size); 697 698 status_t err; 699 switch (code) { 700 case GET_PARAMETER: 701 err = getParameter(node, index, params, size); 702 break; 703 case SET_PARAMETER: 704 err = setParameter(node, index, params, size); 705 break; 706 case GET_CONFIG: 707 err = getConfig(node, index, params, size); 708 break; 709 case SET_CONFIG: 710 err = setConfig(node, index, params, size); 711 break; 712 case SET_INTERNAL_OPTION: 713 { 714 InternalOptionType type = 715 (InternalOptionType)data.readInt32(); 716 717 err = setInternalOption(node, index, type, params, size); 718 break; 719 } 720 721 default: 722 TRESPASS(); 723 } 724 725 reply->writeInt32(err); 726 727 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 728 reply->write(params, size); 729 } 730 731 free(params); 732 params = NULL; 733 734 return NO_ERROR; 735 } 736 737 case GET_STATE: 738 { 739 CHECK_OMX_INTERFACE(IOMX, data, reply); 740 741 node_id node = (node_id)data.readInt32(); 742 OMX_STATETYPE state = OMX_StateInvalid; 743 744 status_t err = getState(node, &state); 745 reply->writeInt32(state); 746 reply->writeInt32(err); 747 748 return NO_ERROR; 749 } 750 751 case ENABLE_GRAPHIC_BUFFERS: 752 { 753 CHECK_OMX_INTERFACE(IOMX, data, reply); 754 755 node_id node = (node_id)data.readInt32(); 756 OMX_U32 port_index = data.readInt32(); 757 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 758 759 status_t err = enableGraphicBuffers(node, port_index, enable); 760 reply->writeInt32(err); 761 762 return NO_ERROR; 763 } 764 765 case GET_GRAPHIC_BUFFER_USAGE: 766 { 767 CHECK_OMX_INTERFACE(IOMX, data, reply); 768 769 node_id node = (node_id)data.readInt32(); 770 OMX_U32 port_index = data.readInt32(); 771 772 OMX_U32 usage = 0; 773 status_t err = getGraphicBufferUsage(node, port_index, &usage); 774 reply->writeInt32(err); 775 reply->writeInt32(usage); 776 777 return NO_ERROR; 778 } 779 780 case USE_BUFFER: 781 { 782 CHECK_OMX_INTERFACE(IOMX, data, reply); 783 784 node_id node = (node_id)data.readInt32(); 785 OMX_U32 port_index = data.readInt32(); 786 sp<IMemory> params = 787 interface_cast<IMemory>(data.readStrongBinder()); 788 OMX_U32 allottedSize = data.readInt32(); 789 790 buffer_id buffer; 791 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize); 792 reply->writeInt32(err); 793 794 if (err == OK) { 795 reply->writeInt32((int32_t)buffer); 796 } 797 798 return NO_ERROR; 799 } 800 801 case USE_GRAPHIC_BUFFER: 802 { 803 CHECK_OMX_INTERFACE(IOMX, data, reply); 804 805 node_id node = (node_id)data.readInt32(); 806 OMX_U32 port_index = data.readInt32(); 807 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 808 data.read(*graphicBuffer); 809 810 buffer_id buffer; 811 status_t err = useGraphicBuffer( 812 node, port_index, graphicBuffer, &buffer); 813 reply->writeInt32(err); 814 815 if (err == OK) { 816 reply->writeInt32((int32_t)buffer); 817 } 818 819 return NO_ERROR; 820 } 821 822 case UPDATE_GRAPHIC_BUFFER_IN_META: 823 { 824 CHECK_OMX_INTERFACE(IOMX, data, reply); 825 826 node_id node = (node_id)data.readInt32(); 827 OMX_U32 port_index = data.readInt32(); 828 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 829 data.read(*graphicBuffer); 830 buffer_id buffer = (buffer_id)data.readInt32(); 831 832 status_t err = updateGraphicBufferInMeta( 833 node, port_index, graphicBuffer, buffer); 834 reply->writeInt32(err); 835 836 return NO_ERROR; 837 } 838 839 case CREATE_INPUT_SURFACE: 840 { 841 CHECK_OMX_INTERFACE(IOMX, data, reply); 842 843 node_id node = (node_id)data.readInt32(); 844 OMX_U32 port_index = data.readInt32(); 845 846 sp<IGraphicBufferProducer> bufferProducer; 847 MetadataBufferType type; 848 status_t err = createInputSurface(node, port_index, &bufferProducer, &type); 849 850 reply->writeInt32(type); 851 reply->writeInt32(err); 852 853 if (err == OK) { 854 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 855 } 856 857 return NO_ERROR; 858 } 859 860 case CREATE_PERSISTENT_INPUT_SURFACE: 861 { 862 CHECK_OMX_INTERFACE(IOMX, data, reply); 863 864 sp<IGraphicBufferProducer> bufferProducer; 865 sp<IGraphicBufferConsumer> bufferConsumer; 866 status_t err = createPersistentInputSurface( 867 &bufferProducer, &bufferConsumer); 868 869 reply->writeInt32(err); 870 871 if (err == OK) { 872 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 873 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer)); 874 } 875 876 return NO_ERROR; 877 } 878 879 case SET_INPUT_SURFACE: 880 { 881 CHECK_OMX_INTERFACE(IOMX, data, reply); 882 883 node_id node = (node_id)data.readInt32(); 884 OMX_U32 port_index = data.readInt32(); 885 886 sp<IGraphicBufferConsumer> bufferConsumer = 887 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder()); 888 889 MetadataBufferType type; 890 status_t err = setInputSurface(node, port_index, bufferConsumer, &type); 891 892 reply->writeInt32(type); 893 reply->writeInt32(err); 894 return NO_ERROR; 895 } 896 897 case SIGNAL_END_OF_INPUT_STREAM: 898 { 899 CHECK_OMX_INTERFACE(IOMX, data, reply); 900 901 node_id node = (node_id)data.readInt32(); 902 903 status_t err = signalEndOfInputStream(node); 904 reply->writeInt32(err); 905 906 return NO_ERROR; 907 } 908 909 case STORE_META_DATA_IN_BUFFERS: 910 { 911 CHECK_OMX_INTERFACE(IOMX, data, reply); 912 913 node_id node = (node_id)data.readInt32(); 914 OMX_U32 port_index = data.readInt32(); 915 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 916 917 MetadataBufferType type; 918 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type); 919 reply->writeInt32(type); 920 reply->writeInt32(err); 921 922 return NO_ERROR; 923 } 924 925 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 926 { 927 CHECK_OMX_INTERFACE(IOMX, data, reply); 928 929 node_id node = (node_id)data.readInt32(); 930 OMX_U32 port_index = data.readInt32(); 931 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 932 OMX_U32 max_width = data.readInt32(); 933 OMX_U32 max_height = data.readInt32(); 934 935 status_t err = prepareForAdaptivePlayback( 936 node, port_index, enable, max_width, max_height); 937 reply->writeInt32(err); 938 939 return NO_ERROR; 940 } 941 942 case CONFIGURE_VIDEO_TUNNEL_MODE: 943 { 944 CHECK_OMX_INTERFACE(IOMX, data, reply); 945 946 node_id node = (node_id)data.readInt32(); 947 OMX_U32 port_index = data.readInt32(); 948 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 949 OMX_U32 audio_hw_sync = data.readInt32(); 950 951 native_handle_t *sideband_handle; 952 status_t err = configureVideoTunnelMode( 953 node, port_index, tunneled, audio_hw_sync, &sideband_handle); 954 reply->writeInt32(err); 955 reply->writeNativeHandle(sideband_handle); 956 957 return NO_ERROR; 958 } 959 960 case ALLOC_BUFFER: 961 { 962 CHECK_OMX_INTERFACE(IOMX, data, reply); 963 964 node_id node = (node_id)data.readInt32(); 965 OMX_U32 port_index = data.readInt32(); 966 size_t size = data.readInt64(); 967 968 buffer_id buffer; 969 void *buffer_data; 970 status_t err = allocateBuffer( 971 node, port_index, size, &buffer, &buffer_data); 972 reply->writeInt32(err); 973 974 if (err == OK) { 975 reply->writeInt32((int32_t)buffer); 976 reply->writeInt64((uintptr_t)buffer_data); 977 } 978 979 return NO_ERROR; 980 } 981 982 case ALLOC_BUFFER_WITH_BACKUP: 983 { 984 CHECK_OMX_INTERFACE(IOMX, data, reply); 985 986 node_id node = (node_id)data.readInt32(); 987 OMX_U32 port_index = data.readInt32(); 988 sp<IMemory> params = 989 interface_cast<IMemory>(data.readStrongBinder()); 990 OMX_U32 allottedSize = data.readInt32(); 991 992 buffer_id buffer; 993 status_t err = allocateBufferWithBackup( 994 node, port_index, params, &buffer, allottedSize); 995 996 reply->writeInt32(err); 997 998 if (err == OK) { 999 reply->writeInt32((int32_t)buffer); 1000 } 1001 1002 return NO_ERROR; 1003 } 1004 1005 case FREE_BUFFER: 1006 { 1007 CHECK_OMX_INTERFACE(IOMX, data, reply); 1008 1009 node_id node = (node_id)data.readInt32(); 1010 OMX_U32 port_index = data.readInt32(); 1011 buffer_id buffer = (buffer_id)data.readInt32(); 1012 reply->writeInt32(freeBuffer(node, port_index, buffer)); 1013 1014 return NO_ERROR; 1015 } 1016 1017 case FILL_BUFFER: 1018 { 1019 CHECK_OMX_INTERFACE(IOMX, data, reply); 1020 1021 node_id node = (node_id)data.readInt32(); 1022 buffer_id buffer = (buffer_id)data.readInt32(); 1023 bool haveFence = data.readInt32(); 1024 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1025 reply->writeInt32(fillBuffer(node, buffer, fenceFd)); 1026 1027 return NO_ERROR; 1028 } 1029 1030 case EMPTY_BUFFER: 1031 { 1032 CHECK_OMX_INTERFACE(IOMX, data, reply); 1033 1034 node_id node = (node_id)data.readInt32(); 1035 buffer_id buffer = (buffer_id)data.readInt32(); 1036 OMX_U32 range_offset = data.readInt32(); 1037 OMX_U32 range_length = data.readInt32(); 1038 OMX_U32 flags = data.readInt32(); 1039 OMX_TICKS timestamp = data.readInt64(); 1040 bool haveFence = data.readInt32(); 1041 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1042 reply->writeInt32(emptyBuffer( 1043 node, buffer, range_offset, range_length, flags, timestamp, fenceFd)); 1044 1045 return NO_ERROR; 1046 } 1047 1048 case GET_EXTENSION_INDEX: 1049 { 1050 CHECK_OMX_INTERFACE(IOMX, data, reply); 1051 1052 node_id node = (node_id)data.readInt32(); 1053 const char *parameter_name = data.readCString(); 1054 1055 OMX_INDEXTYPE index; 1056 status_t err = getExtensionIndex(node, parameter_name, &index); 1057 1058 reply->writeInt32(err); 1059 1060 if (err == OK) { 1061 reply->writeInt32(index); 1062 } 1063 1064 return OK; 1065 } 1066 1067 default: 1068 return BBinder::onTransact(code, data, reply, flags); 1069 } 1070 } 1071 1072 //////////////////////////////////////////////////////////////////////////////// 1073 1074 class BpOMXObserver : public BpInterface<IOMXObserver> { 1075 public: 1076 BpOMXObserver(const sp<IBinder> &impl) 1077 : BpInterface<IOMXObserver>(impl) { 1078 } 1079 1080 virtual void onMessages(const std::list<omx_message> &messages) { 1081 Parcel data, reply; 1082 std::list<omx_message>::const_iterator it = messages.cbegin(); 1083 bool first = true; 1084 while (it != messages.cend()) { 1085 const omx_message &msg = *it++; 1086 if (first) { 1087 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1088 data.writeInt32(msg.node); 1089 first = false; 1090 } 1091 data.writeInt32(msg.fenceFd >= 0); 1092 if (msg.fenceFd >= 0) { 1093 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 1094 } 1095 data.writeInt32(msg.type); 1096 data.write(&msg.u, sizeof(msg.u)); 1097 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1098 } 1099 if (!first) { 1100 data.writeInt32(-1); // mark end 1101 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1102 } 1103 } 1104 }; 1105 1106 IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1107 1108 status_t BnOMXObserver::onTransact( 1109 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1110 switch (code) { 1111 case OBSERVER_ON_MSG: 1112 { 1113 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1114 IOMX::node_id node = data.readInt32(); 1115 std::list<omx_message> messages; 1116 status_t err = FAILED_TRANSACTION; // must receive at least one message 1117 do { 1118 int haveFence = data.readInt32(); 1119 if (haveFence < 0) { // we use -1 to mark end of messages 1120 break; 1121 } 1122 omx_message msg; 1123 msg.node = node; 1124 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1125 msg.type = (typeof(msg.type))data.readInt32(); 1126 err = data.read(&msg.u, sizeof(msg.u)); 1127 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1128 messages.push_back(msg); 1129 } while (err == OK); 1130 1131 if (err == OK) { 1132 onMessages(messages); 1133 } 1134 1135 return err; 1136 } 1137 1138 default: 1139 return BBinder::onTransact(code, data, reply, flags); 1140 } 1141 } 1142 1143 } // namespace android 1144