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