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