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