IOMX.cpp revision 22d12769b3b1295f62d02086fc828b0a614b8da6
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 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 62class BpOMX : public BpInterface<IOMX> { 63public: 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 (err == OK && 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 590IMPLEMENT_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 600status_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 = kMetadataBufferTypeInvalid; 848 status_t err = createInputSurface(node, port_index, &bufferProducer, &type); 849 850 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 851 android_errorWriteLog(0x534e4554, "26324358"); 852 } 853 854 reply->writeInt32(type); 855 reply->writeInt32(err); 856 857 if (err == OK) { 858 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 859 } 860 861 return NO_ERROR; 862 } 863 864 case CREATE_PERSISTENT_INPUT_SURFACE: 865 { 866 CHECK_OMX_INTERFACE(IOMX, data, reply); 867 868 sp<IGraphicBufferProducer> bufferProducer; 869 sp<IGraphicBufferConsumer> bufferConsumer; 870 status_t err = createPersistentInputSurface( 871 &bufferProducer, &bufferConsumer); 872 873 reply->writeInt32(err); 874 875 if (err == OK) { 876 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 877 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer)); 878 } 879 880 return NO_ERROR; 881 } 882 883 case SET_INPUT_SURFACE: 884 { 885 CHECK_OMX_INTERFACE(IOMX, data, reply); 886 887 node_id node = (node_id)data.readInt32(); 888 OMX_U32 port_index = data.readInt32(); 889 890 sp<IGraphicBufferConsumer> bufferConsumer = 891 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder()); 892 893 MetadataBufferType type = kMetadataBufferTypeInvalid; 894 status_t err = setInputSurface(node, port_index, bufferConsumer, &type); 895 896 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 897 android_errorWriteLog(0x534e4554, "26324358"); 898 } 899 900 reply->writeInt32(type); 901 reply->writeInt32(err); 902 return NO_ERROR; 903 } 904 905 case SIGNAL_END_OF_INPUT_STREAM: 906 { 907 CHECK_OMX_INTERFACE(IOMX, data, reply); 908 909 node_id node = (node_id)data.readInt32(); 910 911 status_t err = signalEndOfInputStream(node); 912 reply->writeInt32(err); 913 914 return NO_ERROR; 915 } 916 917 case STORE_META_DATA_IN_BUFFERS: 918 { 919 CHECK_OMX_INTERFACE(IOMX, data, reply); 920 921 node_id node = (node_id)data.readInt32(); 922 OMX_U32 port_index = data.readInt32(); 923 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 924 925 MetadataBufferType type = kMetadataBufferTypeInvalid; 926 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type); 927 928 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 929 android_errorWriteLog(0x534e4554, "26324358"); 930 } 931 932 reply->writeInt32(type); 933 reply->writeInt32(err); 934 935 return NO_ERROR; 936 } 937 938 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 939 { 940 CHECK_OMX_INTERFACE(IOMX, data, reply); 941 942 node_id node = (node_id)data.readInt32(); 943 OMX_U32 port_index = data.readInt32(); 944 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 945 OMX_U32 max_width = data.readInt32(); 946 OMX_U32 max_height = data.readInt32(); 947 948 status_t err = prepareForAdaptivePlayback( 949 node, port_index, enable, max_width, max_height); 950 reply->writeInt32(err); 951 952 return NO_ERROR; 953 } 954 955 case CONFIGURE_VIDEO_TUNNEL_MODE: 956 { 957 CHECK_OMX_INTERFACE(IOMX, data, reply); 958 959 node_id node = (node_id)data.readInt32(); 960 OMX_U32 port_index = data.readInt32(); 961 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 962 OMX_U32 audio_hw_sync = data.readInt32(); 963 964 native_handle_t *sideband_handle = NULL; 965 status_t err = configureVideoTunnelMode( 966 node, port_index, tunneled, audio_hw_sync, &sideband_handle); 967 reply->writeInt32(err); 968 if(err == OK){ 969 reply->writeNativeHandle(sideband_handle); 970 } 971 972 return NO_ERROR; 973 } 974 975 case ALLOC_BUFFER: 976 { 977 CHECK_OMX_INTERFACE(IOMX, data, reply); 978 979 node_id node = (node_id)data.readInt32(); 980 OMX_U32 port_index = data.readInt32(); 981 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) { 982 ALOGE("b/24310423"); 983 reply->writeInt32(INVALID_OPERATION); 984 return NO_ERROR; 985 } 986 987 size_t size = data.readInt64(); 988 989 buffer_id buffer; 990 void *buffer_data; 991 status_t err = allocateBuffer( 992 node, port_index, size, &buffer, &buffer_data); 993 reply->writeInt32(err); 994 995 if (err == OK) { 996 reply->writeInt32((int32_t)buffer); 997 reply->writeInt64((uintptr_t)buffer_data); 998 } 999 1000 return NO_ERROR; 1001 } 1002 1003 case ALLOC_BUFFER_WITH_BACKUP: 1004 { 1005 CHECK_OMX_INTERFACE(IOMX, data, reply); 1006 1007 node_id node = (node_id)data.readInt32(); 1008 OMX_U32 port_index = data.readInt32(); 1009 sp<IMemory> params = 1010 interface_cast<IMemory>(data.readStrongBinder()); 1011 OMX_U32 allottedSize = data.readInt32(); 1012 1013 buffer_id buffer; 1014 status_t err = allocateBufferWithBackup( 1015 node, port_index, params, &buffer, allottedSize); 1016 1017 reply->writeInt32(err); 1018 1019 if (err == OK) { 1020 reply->writeInt32((int32_t)buffer); 1021 } 1022 1023 return NO_ERROR; 1024 } 1025 1026 case FREE_BUFFER: 1027 { 1028 CHECK_OMX_INTERFACE(IOMX, data, reply); 1029 1030 node_id node = (node_id)data.readInt32(); 1031 OMX_U32 port_index = data.readInt32(); 1032 buffer_id buffer = (buffer_id)data.readInt32(); 1033 reply->writeInt32(freeBuffer(node, port_index, buffer)); 1034 1035 return NO_ERROR; 1036 } 1037 1038 case FILL_BUFFER: 1039 { 1040 CHECK_OMX_INTERFACE(IOMX, data, reply); 1041 1042 node_id node = (node_id)data.readInt32(); 1043 buffer_id buffer = (buffer_id)data.readInt32(); 1044 bool haveFence = data.readInt32(); 1045 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1046 reply->writeInt32(fillBuffer(node, buffer, fenceFd)); 1047 1048 return NO_ERROR; 1049 } 1050 1051 case EMPTY_BUFFER: 1052 { 1053 CHECK_OMX_INTERFACE(IOMX, data, reply); 1054 1055 node_id node = (node_id)data.readInt32(); 1056 buffer_id buffer = (buffer_id)data.readInt32(); 1057 OMX_U32 range_offset = data.readInt32(); 1058 OMX_U32 range_length = data.readInt32(); 1059 OMX_U32 flags = data.readInt32(); 1060 OMX_TICKS timestamp = data.readInt64(); 1061 bool haveFence = data.readInt32(); 1062 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1063 reply->writeInt32(emptyBuffer( 1064 node, buffer, range_offset, range_length, flags, timestamp, fenceFd)); 1065 1066 return NO_ERROR; 1067 } 1068 1069 case GET_EXTENSION_INDEX: 1070 { 1071 CHECK_OMX_INTERFACE(IOMX, data, reply); 1072 1073 node_id node = (node_id)data.readInt32(); 1074 const char *parameter_name = data.readCString(); 1075 1076 OMX_INDEXTYPE index; 1077 status_t err = getExtensionIndex(node, parameter_name, &index); 1078 1079 reply->writeInt32(err); 1080 1081 if (err == OK) { 1082 reply->writeInt32(index); 1083 } 1084 1085 return OK; 1086 } 1087 1088 default: 1089 return BBinder::onTransact(code, data, reply, flags); 1090 } 1091} 1092 1093//////////////////////////////////////////////////////////////////////////////// 1094 1095class BpOMXObserver : public BpInterface<IOMXObserver> { 1096public: 1097 BpOMXObserver(const sp<IBinder> &impl) 1098 : BpInterface<IOMXObserver>(impl) { 1099 } 1100 1101 virtual void onMessages(const std::list<omx_message> &messages) { 1102 Parcel data, reply; 1103 std::list<omx_message>::const_iterator it = messages.cbegin(); 1104 bool first = true; 1105 while (it != messages.cend()) { 1106 const omx_message &msg = *it++; 1107 if (first) { 1108 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1109 data.writeInt32(msg.node); 1110 first = false; 1111 } 1112 data.writeInt32(msg.fenceFd >= 0); 1113 if (msg.fenceFd >= 0) { 1114 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 1115 } 1116 data.writeInt32(msg.type); 1117 data.write(&msg.u, sizeof(msg.u)); 1118 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1119 } 1120 if (!first) { 1121 data.writeInt32(-1); // mark end 1122 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1123 } 1124 } 1125}; 1126 1127IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1128 1129status_t BnOMXObserver::onTransact( 1130 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1131 switch (code) { 1132 case OBSERVER_ON_MSG: 1133 { 1134 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1135 IOMX::node_id node = data.readInt32(); 1136 std::list<omx_message> messages; 1137 status_t err = FAILED_TRANSACTION; // must receive at least one message 1138 do { 1139 int haveFence = data.readInt32(); 1140 if (haveFence < 0) { // we use -1 to mark end of messages 1141 break; 1142 } 1143 omx_message msg; 1144 msg.node = node; 1145 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1146 msg.type = (typeof(msg.type))data.readInt32(); 1147 err = data.read(&msg.u, sizeof(msg.u)); 1148 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1149 messages.push_back(msg); 1150 } while (err == OK); 1151 1152 if (err == OK) { 1153 onMessages(messages); 1154 } 1155 1156 return err; 1157 } 1158 1159 default: 1160 return BBinder::onTransact(code, data, reply, flags); 1161 } 1162} 1163 1164} // namespace android 1165