IOMX.cpp revision 776aacce9e5e2dfbc4e7a955916ea0d397af74bf
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 (err == OK && 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 status_t err = NO_MEMORY; 622 void *params = calloc(size, 1); 623 if (params) { 624 err = data.read(params, size); 625 if (err != OK) { 626 android_errorWriteLog(0x534e4554, "26914474"); 627 } else { 628 switch (code) { 629 case GET_PARAMETER: 630 err = getParameter(node, index, params, size); 631 break; 632 case SET_PARAMETER: 633 err = setParameter(node, index, params, size); 634 break; 635 case GET_CONFIG: 636 err = getConfig(node, index, params, size); 637 break; 638 case SET_CONFIG: 639 err = setConfig(node, index, params, size); 640 break; 641 case SET_INTERNAL_OPTION: 642 { 643 InternalOptionType type = 644 (InternalOptionType)data.readInt32(); 645 646 err = setInternalOption(node, index, type, params, size); 647 break; 648 } 649 650 default: 651 TRESPASS(); 652 } 653 } 654 } 655 656 reply->writeInt32(err); 657 658 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 659 reply->write(params, size); 660 } 661 662 free(params); 663 params = NULL; 664 665 return NO_ERROR; 666 } 667 668 case GET_STATE: 669 { 670 CHECK_OMX_INTERFACE(IOMX, data, reply); 671 672 node_id node = (node_id)data.readInt32(); 673 OMX_STATETYPE state = OMX_StateInvalid; 674 675 status_t err = getState(node, &state); 676 reply->writeInt32(state); 677 reply->writeInt32(err); 678 679 return NO_ERROR; 680 } 681 682 case ENABLE_GRAPHIC_BUFFERS: 683 { 684 CHECK_OMX_INTERFACE(IOMX, data, reply); 685 686 node_id node = (node_id)data.readInt32(); 687 OMX_U32 port_index = data.readInt32(); 688 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 689 690 status_t err = enableGraphicBuffers(node, port_index, enable); 691 reply->writeInt32(err); 692 693 return NO_ERROR; 694 } 695 696 case GET_GRAPHIC_BUFFER_USAGE: 697 { 698 CHECK_OMX_INTERFACE(IOMX, data, reply); 699 700 node_id node = (node_id)data.readInt32(); 701 OMX_U32 port_index = data.readInt32(); 702 703 OMX_U32 usage = 0; 704 status_t err = getGraphicBufferUsage(node, port_index, &usage); 705 reply->writeInt32(err); 706 reply->writeInt32(usage); 707 708 return NO_ERROR; 709 } 710 711 case USE_BUFFER: 712 { 713 CHECK_OMX_INTERFACE(IOMX, data, reply); 714 715 node_id node = (node_id)data.readInt32(); 716 OMX_U32 port_index = data.readInt32(); 717 sp<IMemory> params = 718 interface_cast<IMemory>(data.readStrongBinder()); 719 720 buffer_id buffer; 721 status_t err = useBuffer(node, port_index, params, &buffer); 722 reply->writeInt32(err); 723 724 if (err == OK) { 725 reply->writeInt32((int32_t)buffer); 726 } 727 728 return NO_ERROR; 729 } 730 731 case USE_GRAPHIC_BUFFER: 732 { 733 CHECK_OMX_INTERFACE(IOMX, data, reply); 734 735 node_id node = (node_id)data.readInt32(); 736 OMX_U32 port_index = data.readInt32(); 737 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 738 data.read(*graphicBuffer); 739 740 buffer_id buffer; 741 status_t err = useGraphicBuffer( 742 node, port_index, graphicBuffer, &buffer); 743 reply->writeInt32(err); 744 745 if (err == OK) { 746 reply->writeInt32((int32_t)buffer); 747 } 748 749 return NO_ERROR; 750 } 751 752 case UPDATE_GRAPHIC_BUFFER_IN_META: 753 { 754 CHECK_OMX_INTERFACE(IOMX, data, reply); 755 756 node_id node = (node_id)data.readInt32(); 757 OMX_U32 port_index = data.readInt32(); 758 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 759 data.read(*graphicBuffer); 760 buffer_id buffer = (buffer_id)data.readInt32(); 761 762 status_t err = updateGraphicBufferInMeta( 763 node, port_index, graphicBuffer, buffer); 764 reply->writeInt32(err); 765 766 return NO_ERROR; 767 } 768 769 case CREATE_INPUT_SURFACE: 770 { 771 CHECK_OMX_INTERFACE(IOMX, data, reply); 772 773 node_id node = (node_id)data.readInt32(); 774 OMX_U32 port_index = data.readInt32(); 775 776 sp<IGraphicBufferProducer> bufferProducer; 777 status_t err = createInputSurface(node, port_index, 778 &bufferProducer); 779 780 reply->writeInt32(err); 781 782 if (err == OK) { 783 reply->writeStrongBinder(bufferProducer->asBinder()); 784 } 785 786 return NO_ERROR; 787 } 788 789 case SIGNAL_END_OF_INPUT_STREAM: 790 { 791 CHECK_OMX_INTERFACE(IOMX, data, reply); 792 793 node_id node = (node_id)data.readInt32(); 794 795 status_t err = signalEndOfInputStream(node); 796 reply->writeInt32(err); 797 798 return NO_ERROR; 799 } 800 801 case STORE_META_DATA_IN_BUFFERS: 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 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 808 809 status_t err = storeMetaDataInBuffers(node, port_index, enable); 810 reply->writeInt32(err); 811 812 return NO_ERROR; 813 } 814 815 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 816 { 817 CHECK_OMX_INTERFACE(IOMX, data, reply); 818 819 node_id node = (node_id)data.readInt32(); 820 OMX_U32 port_index = data.readInt32(); 821 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 822 OMX_U32 max_width = data.readInt32(); 823 OMX_U32 max_height = data.readInt32(); 824 825 status_t err = prepareForAdaptivePlayback( 826 node, port_index, enable, max_width, max_height); 827 reply->writeInt32(err); 828 829 return NO_ERROR; 830 } 831 832 case CONFIGURE_VIDEO_TUNNEL_MODE: 833 { 834 CHECK_OMX_INTERFACE(IOMX, data, reply); 835 836 node_id node = (node_id)data.readInt32(); 837 OMX_U32 port_index = data.readInt32(); 838 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 839 OMX_U32 audio_hw_sync = data.readInt32(); 840 841 native_handle_t *sideband_handle = NULL; 842 status_t err = configureVideoTunnelMode( 843 node, port_index, tunneled, audio_hw_sync, &sideband_handle); 844 reply->writeInt32(err); 845 if(err == OK){ 846 reply->writeNativeHandle(sideband_handle); 847 } 848 849 return NO_ERROR; 850 } 851 852 case ALLOC_BUFFER: 853 { 854 CHECK_OMX_INTERFACE(IOMX, data, reply); 855 856 node_id node = (node_id)data.readInt32(); 857 OMX_U32 port_index = data.readInt32(); 858 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) { 859 ALOGE("b/24310423"); 860 reply->writeInt32(INVALID_OPERATION); 861 return NO_ERROR; 862 } 863 864 size_t size = data.readInt64(); 865 866 buffer_id buffer; 867 void *buffer_data; 868 status_t err = allocateBuffer( 869 node, port_index, size, &buffer, &buffer_data); 870 reply->writeInt32(err); 871 872 if (err == OK) { 873 reply->writeInt32((int32_t)buffer); 874 reply->writeInt64((uintptr_t)buffer_data); 875 } 876 877 return NO_ERROR; 878 } 879 880 case ALLOC_BUFFER_WITH_BACKUP: 881 { 882 CHECK_OMX_INTERFACE(IOMX, data, reply); 883 884 node_id node = (node_id)data.readInt32(); 885 OMX_U32 port_index = data.readInt32(); 886 sp<IMemory> params = 887 interface_cast<IMemory>(data.readStrongBinder()); 888 889 buffer_id buffer; 890 status_t err = allocateBufferWithBackup( 891 node, port_index, params, &buffer); 892 893 reply->writeInt32(err); 894 895 if (err == OK) { 896 reply->writeInt32((int32_t)buffer); 897 } 898 899 return NO_ERROR; 900 } 901 902 case FREE_BUFFER: 903 { 904 CHECK_OMX_INTERFACE(IOMX, data, reply); 905 906 node_id node = (node_id)data.readInt32(); 907 OMX_U32 port_index = data.readInt32(); 908 buffer_id buffer = (buffer_id)data.readInt32(); 909 reply->writeInt32(freeBuffer(node, port_index, buffer)); 910 911 return NO_ERROR; 912 } 913 914 case FILL_BUFFER: 915 { 916 CHECK_OMX_INTERFACE(IOMX, data, reply); 917 918 node_id node = (node_id)data.readInt32(); 919 buffer_id buffer = (buffer_id)data.readInt32(); 920 reply->writeInt32(fillBuffer(node, buffer)); 921 922 return NO_ERROR; 923 } 924 925 case EMPTY_BUFFER: 926 { 927 CHECK_OMX_INTERFACE(IOMX, data, reply); 928 929 node_id node = (node_id)data.readInt32(); 930 buffer_id buffer = (buffer_id)data.readInt32(); 931 OMX_U32 range_offset = data.readInt32(); 932 OMX_U32 range_length = data.readInt32(); 933 OMX_U32 flags = data.readInt32(); 934 OMX_TICKS timestamp = data.readInt64(); 935 936 reply->writeInt32( 937 emptyBuffer( 938 node, buffer, range_offset, range_length, 939 flags, timestamp)); 940 941 return NO_ERROR; 942 } 943 944 case GET_EXTENSION_INDEX: 945 { 946 CHECK_OMX_INTERFACE(IOMX, data, reply); 947 948 node_id node = (node_id)data.readInt32(); 949 const char *parameter_name = data.readCString(); 950 951 OMX_INDEXTYPE index; 952 status_t err = getExtensionIndex(node, parameter_name, &index); 953 954 reply->writeInt32(err); 955 956 if (err == OK) { 957 reply->writeInt32(index); 958 } 959 960 return OK; 961 } 962 963 default: 964 return BBinder::onTransact(code, data, reply, flags); 965 } 966} 967 968//////////////////////////////////////////////////////////////////////////////// 969 970class BpOMXObserver : public BpInterface<IOMXObserver> { 971public: 972 BpOMXObserver(const sp<IBinder> &impl) 973 : BpInterface<IOMXObserver>(impl) { 974 } 975 976 virtual void onMessage(const omx_message &msg) { 977 Parcel data, reply; 978 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 979 data.write(&msg, sizeof(msg)); 980 981 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 982 983 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 984 } 985}; 986 987IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 988 989status_t BnOMXObserver::onTransact( 990 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 991 switch (code) { 992 case OBSERVER_ON_MSG: 993 { 994 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 995 996 omx_message msg; 997 data.read(&msg, sizeof(msg)); 998 999 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1000 1001 // XXX Could use readInplace maybe? 1002 onMessage(msg); 1003 1004 return NO_ERROR; 1005 } 1006 1007 default: 1008 return BBinder::onTransact(code, data, reply, flags); 1009 } 1010} 1011 1012} // namespace android 1013