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