IOMX.cpp revision cc7cc67349b7a3f498882087aa42ffc05a2daf11
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) { 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 err = reply.readInt32(); 322 if (err != OK) { 323 return err; 324 } 325 326 *bufferProducer = IGraphicBufferProducer::asInterface( 327 reply.readStrongBinder()); 328 329 return err; 330 } 331 332 virtual status_t createPersistentInputSurface( 333 sp<IGraphicBufferProducer> *bufferProducer, 334 sp<IGraphicBufferConsumer> *bufferConsumer) { 335 Parcel data, reply; 336 status_t err; 337 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 338 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply); 339 if (err != OK) { 340 ALOGW("binder transaction failed: %d", err); 341 return err; 342 } 343 344 err = reply.readInt32(); 345 if (err != OK) { 346 return err; 347 } 348 349 *bufferProducer = IGraphicBufferProducer::asInterface( 350 reply.readStrongBinder()); 351 *bufferConsumer = IGraphicBufferConsumer::asInterface( 352 reply.readStrongBinder()); 353 354 return err; 355 } 356 357 virtual status_t setInputSurface( 358 node_id node, OMX_U32 port_index, 359 const sp<IGraphicBufferConsumer> &bufferConsumer) { 360 Parcel data, reply; 361 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 362 status_t err; 363 data.writeInt32((int32_t)node); 364 data.writeInt32(port_index); 365 data.writeStrongBinder(IInterface::asBinder(bufferConsumer)); 366 367 err = remote()->transact(SET_INPUT_SURFACE, data, &reply); 368 369 if (err != OK) { 370 ALOGW("binder transaction failed: %d", err); 371 return err; 372 } 373 return reply.readInt32(); 374 } 375 376 virtual status_t signalEndOfInputStream(node_id node) { 377 Parcel data, reply; 378 status_t err; 379 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 380 data.writeInt32((int32_t)node); 381 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply); 382 if (err != OK) { 383 ALOGW("binder transaction failed: %d", err); 384 return err; 385 } 386 387 return reply.readInt32(); 388 } 389 390 virtual status_t storeMetaDataInBuffers( 391 node_id node, OMX_U32 port_index, OMX_BOOL enable) { 392 Parcel data, reply; 393 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 394 data.writeInt32((int32_t)node); 395 data.writeInt32(port_index); 396 data.writeInt32((uint32_t)enable); 397 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); 398 399 status_t err = reply.readInt32(); 400 return err; 401 } 402 403 virtual status_t prepareForAdaptivePlayback( 404 node_id node, OMX_U32 port_index, OMX_BOOL enable, 405 OMX_U32 max_width, OMX_U32 max_height) { 406 Parcel data, reply; 407 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 408 data.writeInt32((int32_t)node); 409 data.writeInt32(port_index); 410 data.writeInt32((int32_t)enable); 411 data.writeInt32(max_width); 412 data.writeInt32(max_height); 413 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply); 414 415 status_t err = reply.readInt32(); 416 return err; 417 } 418 419 virtual status_t configureVideoTunnelMode( 420 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, 421 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) { 422 Parcel data, reply; 423 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 424 data.writeInt32((int32_t)node); 425 data.writeInt32(portIndex); 426 data.writeInt32((int32_t)tunneled); 427 data.writeInt32(audioHwSync); 428 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply); 429 430 status_t err = reply.readInt32(); 431 if (sidebandHandle) { 432 *sidebandHandle = (native_handle_t *)reply.readNativeHandle(); 433 } 434 return err; 435 } 436 437 438 virtual status_t allocateBuffer( 439 node_id node, OMX_U32 port_index, size_t size, 440 buffer_id *buffer, void **buffer_data) { 441 Parcel data, reply; 442 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 443 data.writeInt32((int32_t)node); 444 data.writeInt32(port_index); 445 data.writeInt64(size); 446 remote()->transact(ALLOC_BUFFER, data, &reply); 447 448 status_t err = reply.readInt32(); 449 if (err != OK) { 450 *buffer = 0; 451 452 return err; 453 } 454 455 *buffer = (buffer_id)reply.readInt32(); 456 *buffer_data = (void *)reply.readInt64(); 457 458 return err; 459 } 460 461 virtual status_t allocateBufferWithBackup( 462 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 463 buffer_id *buffer, OMX_U32 allottedSize) { 464 Parcel data, reply; 465 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 466 data.writeInt32((int32_t)node); 467 data.writeInt32(port_index); 468 data.writeStrongBinder(IInterface::asBinder(params)); 469 data.writeInt32(allottedSize); 470 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply); 471 472 status_t err = reply.readInt32(); 473 if (err != OK) { 474 *buffer = 0; 475 476 return err; 477 } 478 479 *buffer = (buffer_id)reply.readInt32(); 480 481 return err; 482 } 483 484 virtual status_t freeBuffer( 485 node_id node, OMX_U32 port_index, buffer_id buffer) { 486 Parcel data, reply; 487 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 488 data.writeInt32((int32_t)node); 489 data.writeInt32(port_index); 490 data.writeInt32((int32_t)buffer); 491 remote()->transact(FREE_BUFFER, data, &reply); 492 493 return reply.readInt32(); 494 } 495 496 virtual status_t fillBuffer(node_id node, buffer_id buffer) { 497 Parcel data, reply; 498 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 499 data.writeInt32((int32_t)node); 500 data.writeInt32((int32_t)buffer); 501 remote()->transact(FILL_BUFFER, data, &reply); 502 503 return reply.readInt32(); 504 } 505 506 virtual status_t emptyBuffer( 507 node_id node, 508 buffer_id buffer, 509 OMX_U32 range_offset, OMX_U32 range_length, 510 OMX_U32 flags, OMX_TICKS timestamp) { 511 Parcel data, reply; 512 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 513 data.writeInt32((int32_t)node); 514 data.writeInt32((int32_t)buffer); 515 data.writeInt32(range_offset); 516 data.writeInt32(range_length); 517 data.writeInt32(flags); 518 data.writeInt64(timestamp); 519 remote()->transact(EMPTY_BUFFER, data, &reply); 520 521 return reply.readInt32(); 522 } 523 524 virtual status_t getExtensionIndex( 525 node_id node, 526 const char *parameter_name, 527 OMX_INDEXTYPE *index) { 528 Parcel data, reply; 529 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 530 data.writeInt32((int32_t)node); 531 data.writeCString(parameter_name); 532 533 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 534 535 status_t err = reply.readInt32(); 536 if (err == OK) { 537 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 538 } else { 539 *index = OMX_IndexComponentStartUnused; 540 } 541 542 return err; 543 } 544 545 virtual status_t setInternalOption( 546 node_id node, 547 OMX_U32 port_index, 548 InternalOptionType type, 549 const void *optionData, 550 size_t size) { 551 Parcel data, reply; 552 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 553 data.writeInt32((int32_t)node); 554 data.writeInt32(port_index); 555 data.writeInt64(size); 556 data.write(optionData, size); 557 data.writeInt32(type); 558 remote()->transact(SET_INTERNAL_OPTION, data, &reply); 559 560 return reply.readInt32(); 561 } 562}; 563 564IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); 565 566//////////////////////////////////////////////////////////////////////////////// 567 568#define CHECK_OMX_INTERFACE(interface, data, reply) \ 569 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 570 ALOGW("Call incorrectly routed to " #interface); \ 571 return PERMISSION_DENIED; \ 572 } } while (0) 573 574status_t BnOMX::onTransact( 575 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 576 switch (code) { 577 case LIVES_LOCALLY: 578 { 579 CHECK_OMX_INTERFACE(IOMX, data, reply); 580 node_id node = (node_id)data.readInt32(); 581 pid_t pid = (pid_t)data.readInt32(); 582 reply->writeInt32(livesLocally(node, pid)); 583 584 return OK; 585 } 586 587 case LIST_NODES: 588 { 589 CHECK_OMX_INTERFACE(IOMX, data, reply); 590 591 List<ComponentInfo> list; 592 listNodes(&list); 593 594 reply->writeInt32(list.size()); 595 for (List<ComponentInfo>::iterator it = list.begin(); 596 it != list.end(); ++it) { 597 ComponentInfo &cur = *it; 598 599 reply->writeString8(cur.mName); 600 reply->writeInt32(cur.mRoles.size()); 601 for (List<String8>::iterator role_it = cur.mRoles.begin(); 602 role_it != cur.mRoles.end(); ++role_it) { 603 reply->writeString8(*role_it); 604 } 605 } 606 607 return NO_ERROR; 608 } 609 610 case ALLOCATE_NODE: 611 { 612 CHECK_OMX_INTERFACE(IOMX, data, reply); 613 614 const char *name = data.readCString(); 615 616 sp<IOMXObserver> observer = 617 interface_cast<IOMXObserver>(data.readStrongBinder()); 618 619 node_id node; 620 621 status_t err = allocateNode(name, observer, &node); 622 reply->writeInt32(err); 623 if (err == OK) { 624 reply->writeInt32((int32_t)node); 625 } 626 627 return NO_ERROR; 628 } 629 630 case FREE_NODE: 631 { 632 CHECK_OMX_INTERFACE(IOMX, data, reply); 633 634 node_id node = (node_id)data.readInt32(); 635 636 reply->writeInt32(freeNode(node)); 637 638 return NO_ERROR; 639 } 640 641 case SEND_COMMAND: 642 { 643 CHECK_OMX_INTERFACE(IOMX, data, reply); 644 645 node_id node = (node_id)data.readInt32(); 646 647 OMX_COMMANDTYPE cmd = 648 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 649 650 OMX_S32 param = data.readInt32(); 651 reply->writeInt32(sendCommand(node, cmd, param)); 652 653 return NO_ERROR; 654 } 655 656 case GET_PARAMETER: 657 case SET_PARAMETER: 658 case GET_CONFIG: 659 case SET_CONFIG: 660 case SET_INTERNAL_OPTION: 661 { 662 CHECK_OMX_INTERFACE(IOMX, data, reply); 663 664 node_id node = (node_id)data.readInt32(); 665 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 666 667 size_t size = data.readInt64(); 668 669 void *params = malloc(size); 670 data.read(params, size); 671 672 status_t err; 673 switch (code) { 674 case GET_PARAMETER: 675 err = getParameter(node, index, params, size); 676 break; 677 case SET_PARAMETER: 678 err = setParameter(node, index, params, size); 679 break; 680 case GET_CONFIG: 681 err = getConfig(node, index, params, size); 682 break; 683 case SET_CONFIG: 684 err = setConfig(node, index, params, size); 685 break; 686 case SET_INTERNAL_OPTION: 687 { 688 InternalOptionType type = 689 (InternalOptionType)data.readInt32(); 690 691 err = setInternalOption(node, index, type, params, size); 692 break; 693 } 694 695 default: 696 TRESPASS(); 697 } 698 699 reply->writeInt32(err); 700 701 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 702 reply->write(params, size); 703 } 704 705 free(params); 706 params = NULL; 707 708 return NO_ERROR; 709 } 710 711 case GET_STATE: 712 { 713 CHECK_OMX_INTERFACE(IOMX, data, reply); 714 715 node_id node = (node_id)data.readInt32(); 716 OMX_STATETYPE state = OMX_StateInvalid; 717 718 status_t err = getState(node, &state); 719 reply->writeInt32(state); 720 reply->writeInt32(err); 721 722 return NO_ERROR; 723 } 724 725 case ENABLE_GRAPHIC_BUFFERS: 726 { 727 CHECK_OMX_INTERFACE(IOMX, data, reply); 728 729 node_id node = (node_id)data.readInt32(); 730 OMX_U32 port_index = data.readInt32(); 731 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 732 733 status_t err = enableGraphicBuffers(node, port_index, enable); 734 reply->writeInt32(err); 735 736 return NO_ERROR; 737 } 738 739 case GET_GRAPHIC_BUFFER_USAGE: 740 { 741 CHECK_OMX_INTERFACE(IOMX, data, reply); 742 743 node_id node = (node_id)data.readInt32(); 744 OMX_U32 port_index = data.readInt32(); 745 746 OMX_U32 usage = 0; 747 status_t err = getGraphicBufferUsage(node, port_index, &usage); 748 reply->writeInt32(err); 749 reply->writeInt32(usage); 750 751 return NO_ERROR; 752 } 753 754 case USE_BUFFER: 755 { 756 CHECK_OMX_INTERFACE(IOMX, data, reply); 757 758 node_id node = (node_id)data.readInt32(); 759 OMX_U32 port_index = data.readInt32(); 760 sp<IMemory> params = 761 interface_cast<IMemory>(data.readStrongBinder()); 762 OMX_U32 allottedSize = data.readInt32(); 763 764 buffer_id buffer; 765 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize); 766 reply->writeInt32(err); 767 768 if (err == OK) { 769 reply->writeInt32((int32_t)buffer); 770 } 771 772 return NO_ERROR; 773 } 774 775 case USE_GRAPHIC_BUFFER: 776 { 777 CHECK_OMX_INTERFACE(IOMX, data, reply); 778 779 node_id node = (node_id)data.readInt32(); 780 OMX_U32 port_index = data.readInt32(); 781 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 782 data.read(*graphicBuffer); 783 784 buffer_id buffer; 785 status_t err = useGraphicBuffer( 786 node, port_index, graphicBuffer, &buffer); 787 reply->writeInt32(err); 788 789 if (err == OK) { 790 reply->writeInt32((int32_t)buffer); 791 } 792 793 return NO_ERROR; 794 } 795 796 case UPDATE_GRAPHIC_BUFFER_IN_META: 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 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 803 data.read(*graphicBuffer); 804 buffer_id buffer = (buffer_id)data.readInt32(); 805 806 status_t err = updateGraphicBufferInMeta( 807 node, port_index, graphicBuffer, buffer); 808 reply->writeInt32(err); 809 810 return NO_ERROR; 811 } 812 813 case CREATE_INPUT_SURFACE: 814 { 815 CHECK_OMX_INTERFACE(IOMX, data, reply); 816 817 node_id node = (node_id)data.readInt32(); 818 OMX_U32 port_index = data.readInt32(); 819 820 sp<IGraphicBufferProducer> bufferProducer; 821 status_t err = createInputSurface(node, port_index, 822 &bufferProducer); 823 824 reply->writeInt32(err); 825 826 if (err == OK) { 827 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 828 } 829 830 return NO_ERROR; 831 } 832 833 case CREATE_PERSISTENT_INPUT_SURFACE: 834 { 835 CHECK_OMX_INTERFACE(IOMX, data, reply); 836 837 sp<IGraphicBufferProducer> bufferProducer; 838 sp<IGraphicBufferConsumer> bufferConsumer; 839 status_t err = createPersistentInputSurface( 840 &bufferProducer, &bufferConsumer); 841 842 reply->writeInt32(err); 843 844 if (err == OK) { 845 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 846 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer)); 847 } 848 849 return NO_ERROR; 850 } 851 852 case SET_INPUT_SURFACE: 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 859 sp<IGraphicBufferConsumer> bufferConsumer = 860 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder()); 861 862 status_t err = setInputSurface(node, port_index, bufferConsumer); 863 864 reply->writeInt32(err); 865 return NO_ERROR; 866 } 867 868 case SIGNAL_END_OF_INPUT_STREAM: 869 { 870 CHECK_OMX_INTERFACE(IOMX, data, reply); 871 872 node_id node = (node_id)data.readInt32(); 873 874 status_t err = signalEndOfInputStream(node); 875 reply->writeInt32(err); 876 877 return NO_ERROR; 878 } 879 880 case STORE_META_DATA_IN_BUFFERS: 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 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 887 888 status_t err = storeMetaDataInBuffers(node, port_index, enable); 889 reply->writeInt32(err); 890 891 return NO_ERROR; 892 } 893 894 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 895 { 896 CHECK_OMX_INTERFACE(IOMX, data, reply); 897 898 node_id node = (node_id)data.readInt32(); 899 OMX_U32 port_index = data.readInt32(); 900 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 901 OMX_U32 max_width = data.readInt32(); 902 OMX_U32 max_height = data.readInt32(); 903 904 status_t err = prepareForAdaptivePlayback( 905 node, port_index, enable, max_width, max_height); 906 reply->writeInt32(err); 907 908 return NO_ERROR; 909 } 910 911 case CONFIGURE_VIDEO_TUNNEL_MODE: 912 { 913 CHECK_OMX_INTERFACE(IOMX, data, reply); 914 915 node_id node = (node_id)data.readInt32(); 916 OMX_U32 port_index = data.readInt32(); 917 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 918 OMX_U32 audio_hw_sync = data.readInt32(); 919 920 native_handle_t *sideband_handle; 921 status_t err = configureVideoTunnelMode( 922 node, port_index, tunneled, audio_hw_sync, &sideband_handle); 923 reply->writeInt32(err); 924 reply->writeNativeHandle(sideband_handle); 925 926 return NO_ERROR; 927 } 928 929 case ALLOC_BUFFER: 930 { 931 CHECK_OMX_INTERFACE(IOMX, data, reply); 932 933 node_id node = (node_id)data.readInt32(); 934 OMX_U32 port_index = data.readInt32(); 935 size_t size = data.readInt64(); 936 937 buffer_id buffer; 938 void *buffer_data; 939 status_t err = allocateBuffer( 940 node, port_index, size, &buffer, &buffer_data); 941 reply->writeInt32(err); 942 943 if (err == OK) { 944 reply->writeInt32((int32_t)buffer); 945 reply->writeInt64((uintptr_t)buffer_data); 946 } 947 948 return NO_ERROR; 949 } 950 951 case ALLOC_BUFFER_WITH_BACKUP: 952 { 953 CHECK_OMX_INTERFACE(IOMX, data, reply); 954 955 node_id node = (node_id)data.readInt32(); 956 OMX_U32 port_index = data.readInt32(); 957 sp<IMemory> params = 958 interface_cast<IMemory>(data.readStrongBinder()); 959 OMX_U32 allottedSize = data.readInt32(); 960 961 buffer_id buffer; 962 status_t err = allocateBufferWithBackup( 963 node, port_index, params, &buffer, allottedSize); 964 965 reply->writeInt32(err); 966 967 if (err == OK) { 968 reply->writeInt32((int32_t)buffer); 969 } 970 971 return NO_ERROR; 972 } 973 974 case FREE_BUFFER: 975 { 976 CHECK_OMX_INTERFACE(IOMX, data, reply); 977 978 node_id node = (node_id)data.readInt32(); 979 OMX_U32 port_index = data.readInt32(); 980 buffer_id buffer = (buffer_id)data.readInt32(); 981 reply->writeInt32(freeBuffer(node, port_index, buffer)); 982 983 return NO_ERROR; 984 } 985 986 case FILL_BUFFER: 987 { 988 CHECK_OMX_INTERFACE(IOMX, data, reply); 989 990 node_id node = (node_id)data.readInt32(); 991 buffer_id buffer = (buffer_id)data.readInt32(); 992 reply->writeInt32(fillBuffer(node, buffer)); 993 994 return NO_ERROR; 995 } 996 997 case EMPTY_BUFFER: 998 { 999 CHECK_OMX_INTERFACE(IOMX, data, reply); 1000 1001 node_id node = (node_id)data.readInt32(); 1002 buffer_id buffer = (buffer_id)data.readInt32(); 1003 OMX_U32 range_offset = data.readInt32(); 1004 OMX_U32 range_length = data.readInt32(); 1005 OMX_U32 flags = data.readInt32(); 1006 OMX_TICKS timestamp = data.readInt64(); 1007 1008 reply->writeInt32( 1009 emptyBuffer( 1010 node, buffer, range_offset, range_length, 1011 flags, timestamp)); 1012 1013 return NO_ERROR; 1014 } 1015 1016 case GET_EXTENSION_INDEX: 1017 { 1018 CHECK_OMX_INTERFACE(IOMX, data, reply); 1019 1020 node_id node = (node_id)data.readInt32(); 1021 const char *parameter_name = data.readCString(); 1022 1023 OMX_INDEXTYPE index; 1024 status_t err = getExtensionIndex(node, parameter_name, &index); 1025 1026 reply->writeInt32(err); 1027 1028 if (err == OK) { 1029 reply->writeInt32(index); 1030 } 1031 1032 return OK; 1033 } 1034 1035 default: 1036 return BBinder::onTransact(code, data, reply, flags); 1037 } 1038} 1039 1040//////////////////////////////////////////////////////////////////////////////// 1041 1042class BpOMXObserver : public BpInterface<IOMXObserver> { 1043public: 1044 BpOMXObserver(const sp<IBinder> &impl) 1045 : BpInterface<IOMXObserver>(impl) { 1046 } 1047 1048 virtual void onMessage(const omx_message &msg) { 1049 Parcel data, reply; 1050 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1051 data.write(&msg, sizeof(msg)); 1052 1053 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1054 1055 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1056 } 1057}; 1058 1059IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1060 1061status_t BnOMXObserver::onTransact( 1062 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1063 switch (code) { 1064 case OBSERVER_ON_MSG: 1065 { 1066 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1067 1068 omx_message msg; 1069 data.read(&msg, sizeof(msg)); 1070 1071 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1072 1073 // XXX Could use readInplace maybe? 1074 onMessage(msg); 1075 1076 return NO_ERROR; 1077 } 1078 1079 default: 1080 return BBinder::onTransact(code, data, reply, flags); 1081 } 1082} 1083 1084} // namespace android 1085