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