IOMX.cpp revision a63141af8f036bda0b8f7800107ca8a0e0623135
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_NATIVE_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_SECURE_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 enableNativeBuffers( 221 node_id node, OMX_U32 port_index, OMX_BOOL graphic, 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)graphic); 227 data.writeInt32((uint32_t)enable); 228 remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply); 229 230 status_t err = reply.readInt32(); 231 return err; 232 } 233 234 virtual status_t getGraphicBufferUsage( 235 node_id node, OMX_U32 port_index, OMX_U32* usage) { 236 Parcel data, reply; 237 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 238 data.writeInt32((int32_t)node); 239 data.writeInt32(port_index); 240 remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply); 241 242 status_t err = reply.readInt32(); 243 *usage = reply.readInt32(); 244 return err; 245 } 246 247 virtual status_t useBuffer( 248 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 249 buffer_id *buffer, OMX_U32 allottedSize) { 250 Parcel data, reply; 251 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 252 data.writeInt32((int32_t)node); 253 data.writeInt32(port_index); 254 data.writeStrongBinder(IInterface::asBinder(params)); 255 data.writeInt32(allottedSize); 256 remote()->transact(USE_BUFFER, data, &reply); 257 258 status_t err = reply.readInt32(); 259 if (err != OK) { 260 *buffer = 0; 261 262 return err; 263 } 264 265 *buffer = (buffer_id)reply.readInt32(); 266 267 return err; 268 } 269 270 271 virtual status_t useGraphicBuffer( 272 node_id node, OMX_U32 port_index, 273 const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { 274 Parcel data, reply; 275 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 276 data.writeInt32((int32_t)node); 277 data.writeInt32(port_index); 278 data.write(*graphicBuffer); 279 remote()->transact(USE_GRAPHIC_BUFFER, data, &reply); 280 281 status_t err = reply.readInt32(); 282 if (err != OK) { 283 *buffer = 0; 284 285 return err; 286 } 287 288 *buffer = (buffer_id)reply.readInt32(); 289 290 return err; 291 } 292 293 virtual status_t updateGraphicBufferInMeta( 294 node_id node, OMX_U32 port_index, 295 const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) { 296 Parcel data, reply; 297 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 298 data.writeInt32((int32_t)node); 299 data.writeInt32(port_index); 300 data.write(*graphicBuffer); 301 data.writeInt32((int32_t)buffer); 302 remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply); 303 304 status_t err = reply.readInt32(); 305 return err; 306 } 307 308 virtual status_t createInputSurface( 309 node_id node, OMX_U32 port_index, 310 sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) { 311 Parcel data, reply; 312 status_t err; 313 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 314 data.writeInt32((int32_t)node); 315 data.writeInt32(port_index); 316 err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply); 317 if (err != OK) { 318 ALOGW("binder transaction failed: %d", err); 319 return err; 320 } 321 322 // read type even if createInputSurface failed 323 int negotiatedType = reply.readInt32(); 324 if (type != NULL) { 325 *type = (MetadataBufferType)negotiatedType; 326 } 327 328 err = reply.readInt32(); 329 if (err != OK) { 330 return err; 331 } 332 333 *bufferProducer = IGraphicBufferProducer::asInterface( 334 reply.readStrongBinder()); 335 336 return err; 337 } 338 339 virtual status_t createPersistentInputSurface( 340 sp<IGraphicBufferProducer> *bufferProducer, 341 sp<IGraphicBufferConsumer> *bufferConsumer) { 342 Parcel data, reply; 343 status_t err; 344 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 345 err = remote()->transact(CREATE_PERSISTENT_INPUT_SURFACE, data, &reply); 346 if (err != OK) { 347 ALOGW("binder transaction failed: %d", err); 348 return err; 349 } 350 351 err = reply.readInt32(); 352 if (err != OK) { 353 return err; 354 } 355 356 *bufferProducer = IGraphicBufferProducer::asInterface( 357 reply.readStrongBinder()); 358 *bufferConsumer = IGraphicBufferConsumer::asInterface( 359 reply.readStrongBinder()); 360 361 return err; 362 } 363 364 virtual status_t setInputSurface( 365 node_id node, OMX_U32 port_index, 366 const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) { 367 Parcel data, reply; 368 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 369 status_t err; 370 data.writeInt32((int32_t)node); 371 data.writeInt32(port_index); 372 data.writeStrongBinder(IInterface::asBinder(bufferConsumer)); 373 374 err = remote()->transact(SET_INPUT_SURFACE, data, &reply); 375 376 if (err != OK) { 377 ALOGW("binder transaction failed: %d", err); 378 return err; 379 } 380 381 // read type even if setInputSurface failed 382 int negotiatedType = reply.readInt32(); 383 if (type != NULL) { 384 *type = (MetadataBufferType)negotiatedType; 385 } 386 387 return reply.readInt32(); 388 } 389 390 virtual status_t signalEndOfInputStream(node_id node) { 391 Parcel data, reply; 392 status_t err; 393 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 394 data.writeInt32((int32_t)node); 395 err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply); 396 if (err != OK) { 397 ALOGW("binder transaction failed: %d", err); 398 return err; 399 } 400 401 return reply.readInt32(); 402 } 403 404 virtual status_t storeMetaDataInBuffers( 405 node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) { 406 Parcel data, reply; 407 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 408 data.writeInt32((int32_t)node); 409 data.writeInt32(port_index); 410 data.writeInt32((uint32_t)enable); 411 remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply); 412 413 // read type even storeMetaDataInBuffers failed 414 int negotiatedType = reply.readInt32(); 415 if (type != NULL) { 416 *type = (MetadataBufferType)negotiatedType; 417 } 418 419 return reply.readInt32(); 420 } 421 422 virtual status_t prepareForAdaptivePlayback( 423 node_id node, OMX_U32 port_index, OMX_BOOL enable, 424 OMX_U32 max_width, OMX_U32 max_height) { 425 Parcel data, reply; 426 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 427 data.writeInt32((int32_t)node); 428 data.writeInt32(port_index); 429 data.writeInt32((int32_t)enable); 430 data.writeInt32(max_width); 431 data.writeInt32(max_height); 432 remote()->transact(PREPARE_FOR_ADAPTIVE_PLAYBACK, data, &reply); 433 434 status_t err = reply.readInt32(); 435 return err; 436 } 437 438 virtual status_t configureVideoTunnelMode( 439 node_id node, OMX_U32 portIndex, OMX_BOOL tunneled, 440 OMX_U32 audioHwSync, native_handle_t **sidebandHandle ) { 441 Parcel data, reply; 442 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 443 data.writeInt32((int32_t)node); 444 data.writeInt32(portIndex); 445 data.writeInt32((int32_t)tunneled); 446 data.writeInt32(audioHwSync); 447 remote()->transact(CONFIGURE_VIDEO_TUNNEL_MODE, data, &reply); 448 449 status_t err = reply.readInt32(); 450 if (sidebandHandle) { 451 *sidebandHandle = (native_handle_t *)reply.readNativeHandle(); 452 } 453 return err; 454 } 455 456 457 virtual status_t allocateSecureBuffer( 458 node_id node, OMX_U32 port_index, size_t size, 459 buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) { 460 Parcel data, reply; 461 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 462 data.writeInt32((int32_t)node); 463 data.writeInt32(port_index); 464 data.writeInt64(size); 465 remote()->transact(ALLOC_SECURE_BUFFER, data, &reply); 466 467 status_t err = reply.readInt32(); 468 if (err != OK) { 469 *buffer = 0; 470 *buffer_data = NULL; 471 *native_handle = NULL; 472 return err; 473 } 474 475 *buffer = (buffer_id)reply.readInt32(); 476 *buffer_data = (void *)reply.readInt64(); 477 if (*buffer_data == NULL) { 478 *native_handle = reply.readNativeHandle(); 479 } else { 480 *native_handle = NULL; 481 } 482 return err; 483 } 484 485 virtual status_t allocateBufferWithBackup( 486 node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, 487 buffer_id *buffer, OMX_U32 allottedSize) { 488 Parcel data, reply; 489 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 490 data.writeInt32((int32_t)node); 491 data.writeInt32(port_index); 492 data.writeStrongBinder(IInterface::asBinder(params)); 493 data.writeInt32(allottedSize); 494 remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply); 495 496 status_t err = reply.readInt32(); 497 if (err != OK) { 498 *buffer = 0; 499 500 return err; 501 } 502 503 *buffer = (buffer_id)reply.readInt32(); 504 505 return err; 506 } 507 508 virtual status_t freeBuffer( 509 node_id node, OMX_U32 port_index, buffer_id buffer) { 510 Parcel data, reply; 511 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 512 data.writeInt32((int32_t)node); 513 data.writeInt32(port_index); 514 data.writeInt32((int32_t)buffer); 515 remote()->transact(FREE_BUFFER, data, &reply); 516 517 return reply.readInt32(); 518 } 519 520 virtual status_t fillBuffer(node_id node, buffer_id buffer, int fenceFd) { 521 Parcel data, reply; 522 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 523 data.writeInt32((int32_t)node); 524 data.writeInt32((int32_t)buffer); 525 data.writeInt32(fenceFd >= 0); 526 if (fenceFd >= 0) { 527 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 528 } 529 remote()->transact(FILL_BUFFER, data, &reply); 530 531 return reply.readInt32(); 532 } 533 534 virtual status_t emptyBuffer( 535 node_id node, 536 buffer_id buffer, 537 OMX_U32 range_offset, OMX_U32 range_length, 538 OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) { 539 Parcel data, reply; 540 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 541 data.writeInt32((int32_t)node); 542 data.writeInt32((int32_t)buffer); 543 data.writeInt32(range_offset); 544 data.writeInt32(range_length); 545 data.writeInt32(flags); 546 data.writeInt64(timestamp); 547 data.writeInt32(fenceFd >= 0); 548 if (fenceFd >= 0) { 549 data.writeFileDescriptor(fenceFd, true /* takeOwnership */); 550 } 551 remote()->transact(EMPTY_BUFFER, data, &reply); 552 553 return reply.readInt32(); 554 } 555 556 virtual status_t getExtensionIndex( 557 node_id node, 558 const char *parameter_name, 559 OMX_INDEXTYPE *index) { 560 Parcel data, reply; 561 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 562 data.writeInt32((int32_t)node); 563 data.writeCString(parameter_name); 564 565 remote()->transact(GET_EXTENSION_INDEX, data, &reply); 566 567 status_t err = reply.readInt32(); 568 if (err == OK) { 569 *index = static_cast<OMX_INDEXTYPE>(reply.readInt32()); 570 } else { 571 *index = OMX_IndexComponentStartUnused; 572 } 573 574 return err; 575 } 576 577 virtual status_t setInternalOption( 578 node_id node, 579 OMX_U32 port_index, 580 InternalOptionType type, 581 const void *optionData, 582 size_t size) { 583 Parcel data, reply; 584 data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); 585 data.writeInt32((int32_t)node); 586 data.writeInt32(port_index); 587 data.writeInt64(size); 588 data.write(optionData, size); 589 data.writeInt32(type); 590 remote()->transact(SET_INTERNAL_OPTION, data, &reply); 591 592 return reply.readInt32(); 593 } 594}; 595 596IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); 597 598//////////////////////////////////////////////////////////////////////////////// 599 600#define CHECK_OMX_INTERFACE(interface, data, reply) \ 601 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 602 ALOGW("Call incorrectly routed to " #interface); \ 603 return PERMISSION_DENIED; \ 604 } } while (0) 605 606status_t BnOMX::onTransact( 607 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 608 switch (code) { 609 case LIVES_LOCALLY: 610 { 611 CHECK_OMX_INTERFACE(IOMX, data, reply); 612 node_id node = (node_id)data.readInt32(); 613 pid_t pid = (pid_t)data.readInt32(); 614 reply->writeInt32(livesLocally(node, pid)); 615 616 return OK; 617 } 618 619 case LIST_NODES: 620 { 621 CHECK_OMX_INTERFACE(IOMX, data, reply); 622 623 List<ComponentInfo> list; 624 listNodes(&list); 625 626 reply->writeInt32(list.size()); 627 for (List<ComponentInfo>::iterator it = list.begin(); 628 it != list.end(); ++it) { 629 ComponentInfo &cur = *it; 630 631 reply->writeString8(cur.mName); 632 reply->writeInt32(cur.mRoles.size()); 633 for (List<String8>::iterator role_it = cur.mRoles.begin(); 634 role_it != cur.mRoles.end(); ++role_it) { 635 reply->writeString8(*role_it); 636 } 637 } 638 639 return NO_ERROR; 640 } 641 642 case ALLOCATE_NODE: 643 { 644 CHECK_OMX_INTERFACE(IOMX, data, reply); 645 646 const char *name = data.readCString(); 647 648 sp<IOMXObserver> observer = 649 interface_cast<IOMXObserver>(data.readStrongBinder()); 650 651 if (name == NULL || observer == NULL) { 652 ALOGE("b/26392700"); 653 reply->writeInt32(INVALID_OPERATION); 654 return NO_ERROR; 655 } 656 657 node_id node; 658 659 status_t err = allocateNode(name, observer, &node); 660 reply->writeInt32(err); 661 if (err == OK) { 662 reply->writeInt32((int32_t)node); 663 } 664 665 return NO_ERROR; 666 } 667 668 case FREE_NODE: 669 { 670 CHECK_OMX_INTERFACE(IOMX, data, reply); 671 672 node_id node = (node_id)data.readInt32(); 673 674 reply->writeInt32(freeNode(node)); 675 676 return NO_ERROR; 677 } 678 679 case SEND_COMMAND: 680 { 681 CHECK_OMX_INTERFACE(IOMX, data, reply); 682 683 node_id node = (node_id)data.readInt32(); 684 685 OMX_COMMANDTYPE cmd = 686 static_cast<OMX_COMMANDTYPE>(data.readInt32()); 687 688 OMX_S32 param = data.readInt32(); 689 reply->writeInt32(sendCommand(node, cmd, param)); 690 691 return NO_ERROR; 692 } 693 694 case GET_PARAMETER: 695 case SET_PARAMETER: 696 case GET_CONFIG: 697 case SET_CONFIG: 698 case SET_INTERNAL_OPTION: 699 { 700 CHECK_OMX_INTERFACE(IOMX, data, reply); 701 702 node_id node = (node_id)data.readInt32(); 703 OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32()); 704 705 size_t size = data.readInt64(); 706 707 void *params = malloc(size); 708 data.read(params, size); 709 710 status_t err; 711 switch (code) { 712 case GET_PARAMETER: 713 err = getParameter(node, index, params, size); 714 break; 715 case SET_PARAMETER: 716 err = setParameter(node, index, params, size); 717 break; 718 case GET_CONFIG: 719 err = getConfig(node, index, params, size); 720 break; 721 case SET_CONFIG: 722 err = setConfig(node, index, params, size); 723 break; 724 case SET_INTERNAL_OPTION: 725 { 726 InternalOptionType type = 727 (InternalOptionType)data.readInt32(); 728 729 err = setInternalOption(node, index, type, params, size); 730 break; 731 } 732 733 default: 734 TRESPASS(); 735 } 736 737 reply->writeInt32(err); 738 739 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 740 reply->write(params, size); 741 } 742 743 free(params); 744 params = NULL; 745 746 return NO_ERROR; 747 } 748 749 case GET_STATE: 750 { 751 CHECK_OMX_INTERFACE(IOMX, data, reply); 752 753 node_id node = (node_id)data.readInt32(); 754 OMX_STATETYPE state = OMX_StateInvalid; 755 756 status_t err = getState(node, &state); 757 reply->writeInt32(state); 758 reply->writeInt32(err); 759 760 return NO_ERROR; 761 } 762 763 case ENABLE_NATIVE_BUFFERS: 764 { 765 CHECK_OMX_INTERFACE(IOMX, data, reply); 766 767 node_id node = (node_id)data.readInt32(); 768 OMX_U32 port_index = data.readInt32(); 769 OMX_BOOL graphic = (OMX_BOOL)data.readInt32(); 770 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 771 772 status_t err = enableNativeBuffers(node, port_index, graphic, enable); 773 reply->writeInt32(err); 774 775 return NO_ERROR; 776 } 777 778 case GET_GRAPHIC_BUFFER_USAGE: 779 { 780 CHECK_OMX_INTERFACE(IOMX, data, reply); 781 782 node_id node = (node_id)data.readInt32(); 783 OMX_U32 port_index = data.readInt32(); 784 785 OMX_U32 usage = 0; 786 status_t err = getGraphicBufferUsage(node, port_index, &usage); 787 reply->writeInt32(err); 788 reply->writeInt32(usage); 789 790 return NO_ERROR; 791 } 792 793 case USE_BUFFER: 794 { 795 CHECK_OMX_INTERFACE(IOMX, data, reply); 796 797 node_id node = (node_id)data.readInt32(); 798 OMX_U32 port_index = data.readInt32(); 799 sp<IMemory> params = 800 interface_cast<IMemory>(data.readStrongBinder()); 801 OMX_U32 allottedSize = data.readInt32(); 802 803 if (params == NULL) { 804 ALOGE("b/26392700"); 805 reply->writeInt32(INVALID_OPERATION); 806 return NO_ERROR; 807 } 808 809 buffer_id buffer; 810 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize); 811 reply->writeInt32(err); 812 813 if (err == OK) { 814 reply->writeInt32((int32_t)buffer); 815 } 816 817 return NO_ERROR; 818 } 819 820 case USE_GRAPHIC_BUFFER: 821 { 822 CHECK_OMX_INTERFACE(IOMX, data, reply); 823 824 node_id node = (node_id)data.readInt32(); 825 OMX_U32 port_index = data.readInt32(); 826 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 827 data.read(*graphicBuffer); 828 829 buffer_id buffer; 830 status_t err = useGraphicBuffer( 831 node, port_index, graphicBuffer, &buffer); 832 reply->writeInt32(err); 833 834 if (err == OK) { 835 reply->writeInt32((int32_t)buffer); 836 } 837 838 return NO_ERROR; 839 } 840 841 case UPDATE_GRAPHIC_BUFFER_IN_META: 842 { 843 CHECK_OMX_INTERFACE(IOMX, data, reply); 844 845 node_id node = (node_id)data.readInt32(); 846 OMX_U32 port_index = data.readInt32(); 847 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 848 data.read(*graphicBuffer); 849 buffer_id buffer = (buffer_id)data.readInt32(); 850 851 status_t err = updateGraphicBufferInMeta( 852 node, port_index, graphicBuffer, buffer); 853 reply->writeInt32(err); 854 855 return NO_ERROR; 856 } 857 858 case CREATE_INPUT_SURFACE: 859 { 860 CHECK_OMX_INTERFACE(IOMX, data, reply); 861 862 node_id node = (node_id)data.readInt32(); 863 OMX_U32 port_index = data.readInt32(); 864 865 sp<IGraphicBufferProducer> bufferProducer; 866 MetadataBufferType type; 867 status_t err = createInputSurface(node, port_index, &bufferProducer, &type); 868 869 reply->writeInt32(type); 870 reply->writeInt32(err); 871 872 if (err == OK) { 873 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 874 } 875 876 return NO_ERROR; 877 } 878 879 case CREATE_PERSISTENT_INPUT_SURFACE: 880 { 881 CHECK_OMX_INTERFACE(IOMX, data, reply); 882 883 sp<IGraphicBufferProducer> bufferProducer; 884 sp<IGraphicBufferConsumer> bufferConsumer; 885 status_t err = createPersistentInputSurface( 886 &bufferProducer, &bufferConsumer); 887 888 reply->writeInt32(err); 889 890 if (err == OK) { 891 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 892 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer)); 893 } 894 895 return NO_ERROR; 896 } 897 898 case SET_INPUT_SURFACE: 899 { 900 CHECK_OMX_INTERFACE(IOMX, data, reply); 901 902 node_id node = (node_id)data.readInt32(); 903 OMX_U32 port_index = data.readInt32(); 904 905 sp<IGraphicBufferConsumer> bufferConsumer = 906 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder()); 907 908 MetadataBufferType type = kMetadataBufferTypeInvalid; 909 status_t err = INVALID_OPERATION; 910 if (bufferConsumer == NULL) { 911 ALOGE("b/26392700"); 912 } else { 913 err = setInputSurface(node, port_index, bufferConsumer, &type); 914 } 915 916 reply->writeInt32(type); 917 reply->writeInt32(err); 918 return NO_ERROR; 919 } 920 921 case SIGNAL_END_OF_INPUT_STREAM: 922 { 923 CHECK_OMX_INTERFACE(IOMX, data, reply); 924 925 node_id node = (node_id)data.readInt32(); 926 927 status_t err = signalEndOfInputStream(node); 928 reply->writeInt32(err); 929 930 return NO_ERROR; 931 } 932 933 case STORE_META_DATA_IN_BUFFERS: 934 { 935 CHECK_OMX_INTERFACE(IOMX, data, reply); 936 937 node_id node = (node_id)data.readInt32(); 938 OMX_U32 port_index = data.readInt32(); 939 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 940 941 MetadataBufferType type; 942 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type); 943 reply->writeInt32(type); 944 reply->writeInt32(err); 945 946 return NO_ERROR; 947 } 948 949 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 950 { 951 CHECK_OMX_INTERFACE(IOMX, data, reply); 952 953 node_id node = (node_id)data.readInt32(); 954 OMX_U32 port_index = data.readInt32(); 955 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 956 OMX_U32 max_width = data.readInt32(); 957 OMX_U32 max_height = data.readInt32(); 958 959 status_t err = prepareForAdaptivePlayback( 960 node, port_index, enable, max_width, max_height); 961 reply->writeInt32(err); 962 963 return NO_ERROR; 964 } 965 966 case CONFIGURE_VIDEO_TUNNEL_MODE: 967 { 968 CHECK_OMX_INTERFACE(IOMX, data, reply); 969 970 node_id node = (node_id)data.readInt32(); 971 OMX_U32 port_index = data.readInt32(); 972 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 973 OMX_U32 audio_hw_sync = data.readInt32(); 974 975 native_handle_t *sideband_handle = NULL; 976 status_t err = configureVideoTunnelMode( 977 node, port_index, tunneled, audio_hw_sync, &sideband_handle); 978 reply->writeInt32(err); 979 reply->writeNativeHandle(sideband_handle); 980 981 return NO_ERROR; 982 } 983 984 case ALLOC_SECURE_BUFFER: 985 { 986 CHECK_OMX_INTERFACE(IOMX, data, reply); 987 988 node_id node = (node_id)data.readInt32(); 989 OMX_U32 port_index = data.readInt32(); 990 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) { 991 ALOGE("b/24310423"); 992 reply->writeInt32(INVALID_OPERATION); 993 return NO_ERROR; 994 } 995 996 size_t size = data.readInt64(); 997 998 buffer_id buffer; 999 void *buffer_data = NULL; 1000 native_handle_t *native_handle = NULL; 1001 status_t err = allocateSecureBuffer( 1002 node, port_index, size, &buffer, &buffer_data, &native_handle); 1003 reply->writeInt32(err); 1004 1005 if (err == OK) { 1006 reply->writeInt32((int32_t)buffer); 1007 reply->writeInt64((uintptr_t)buffer_data); 1008 if (buffer_data == NULL) { 1009 reply->writeNativeHandle(native_handle); 1010 } 1011 } 1012 1013 return NO_ERROR; 1014 } 1015 1016 case ALLOC_BUFFER_WITH_BACKUP: 1017 { 1018 CHECK_OMX_INTERFACE(IOMX, data, reply); 1019 1020 node_id node = (node_id)data.readInt32(); 1021 OMX_U32 port_index = data.readInt32(); 1022 sp<IMemory> params = 1023 interface_cast<IMemory>(data.readStrongBinder()); 1024 OMX_U32 allottedSize = data.readInt32(); 1025 1026 if (params == NULL) { 1027 ALOGE("b/26392700"); 1028 reply->writeInt32(INVALID_OPERATION); 1029 return NO_ERROR; 1030 } 1031 1032 buffer_id buffer; 1033 status_t err = allocateBufferWithBackup( 1034 node, port_index, params, &buffer, allottedSize); 1035 1036 reply->writeInt32(err); 1037 1038 if (err == OK) { 1039 reply->writeInt32((int32_t)buffer); 1040 } 1041 1042 return NO_ERROR; 1043 } 1044 1045 case FREE_BUFFER: 1046 { 1047 CHECK_OMX_INTERFACE(IOMX, data, reply); 1048 1049 node_id node = (node_id)data.readInt32(); 1050 OMX_U32 port_index = data.readInt32(); 1051 buffer_id buffer = (buffer_id)data.readInt32(); 1052 reply->writeInt32(freeBuffer(node, port_index, buffer)); 1053 1054 return NO_ERROR; 1055 } 1056 1057 case FILL_BUFFER: 1058 { 1059 CHECK_OMX_INTERFACE(IOMX, data, reply); 1060 1061 node_id node = (node_id)data.readInt32(); 1062 buffer_id buffer = (buffer_id)data.readInt32(); 1063 bool haveFence = data.readInt32(); 1064 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1065 reply->writeInt32(fillBuffer(node, buffer, fenceFd)); 1066 1067 return NO_ERROR; 1068 } 1069 1070 case EMPTY_BUFFER: 1071 { 1072 CHECK_OMX_INTERFACE(IOMX, data, reply); 1073 1074 node_id node = (node_id)data.readInt32(); 1075 buffer_id buffer = (buffer_id)data.readInt32(); 1076 OMX_U32 range_offset = data.readInt32(); 1077 OMX_U32 range_length = data.readInt32(); 1078 OMX_U32 flags = data.readInt32(); 1079 OMX_TICKS timestamp = data.readInt64(); 1080 bool haveFence = data.readInt32(); 1081 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1082 reply->writeInt32(emptyBuffer( 1083 node, buffer, range_offset, range_length, flags, timestamp, fenceFd)); 1084 1085 return NO_ERROR; 1086 } 1087 1088 case GET_EXTENSION_INDEX: 1089 { 1090 CHECK_OMX_INTERFACE(IOMX, data, reply); 1091 1092 node_id node = (node_id)data.readInt32(); 1093 const char *parameter_name = data.readCString(); 1094 1095 if (parameter_name == NULL) { 1096 ALOGE("b/26392700"); 1097 reply->writeInt32(INVALID_OPERATION); 1098 return NO_ERROR; 1099 } 1100 1101 OMX_INDEXTYPE index; 1102 status_t err = getExtensionIndex(node, parameter_name, &index); 1103 1104 reply->writeInt32(err); 1105 1106 if (err == OK) { 1107 reply->writeInt32(index); 1108 } 1109 1110 return OK; 1111 } 1112 1113 default: 1114 return BBinder::onTransact(code, data, reply, flags); 1115 } 1116} 1117 1118//////////////////////////////////////////////////////////////////////////////// 1119 1120class BpOMXObserver : public BpInterface<IOMXObserver> { 1121public: 1122 BpOMXObserver(const sp<IBinder> &impl) 1123 : BpInterface<IOMXObserver>(impl) { 1124 } 1125 1126 virtual void onMessages(const std::list<omx_message> &messages) { 1127 Parcel data, reply; 1128 std::list<omx_message>::const_iterator it = messages.cbegin(); 1129 bool first = true; 1130 while (it != messages.cend()) { 1131 const omx_message &msg = *it++; 1132 if (first) { 1133 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1134 data.writeInt32(msg.node); 1135 first = false; 1136 } 1137 data.writeInt32(msg.fenceFd >= 0); 1138 if (msg.fenceFd >= 0) { 1139 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 1140 } 1141 data.writeInt32(msg.type); 1142 data.write(&msg.u, sizeof(msg.u)); 1143 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1144 } 1145 if (!first) { 1146 data.writeInt32(-1); // mark end 1147 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1148 } 1149 } 1150}; 1151 1152IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1153 1154status_t BnOMXObserver::onTransact( 1155 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1156 switch (code) { 1157 case OBSERVER_ON_MSG: 1158 { 1159 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1160 IOMX::node_id node = data.readInt32(); 1161 std::list<omx_message> messages; 1162 status_t err = FAILED_TRANSACTION; // must receive at least one message 1163 do { 1164 int haveFence = data.readInt32(); 1165 if (haveFence < 0) { // we use -1 to mark end of messages 1166 break; 1167 } 1168 omx_message msg; 1169 msg.node = node; 1170 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1171 msg.type = (typeof(msg.type))data.readInt32(); 1172 err = data.read(&msg.u, sizeof(msg.u)); 1173 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1174 messages.push_back(msg); 1175 } while (err == OK); 1176 1177 if (err == OK) { 1178 onMessages(messages); 1179 } 1180 1181 return err; 1182 } 1183 1184 default: 1185 return BBinder::onTransact(code, data, reply, flags); 1186 } 1187} 1188 1189} // namespace android 1190