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