IOMX.cpp revision 7b5795dc605529246b861ff8d8be7c7a58c5bfe2
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 bool isUsageBits = (index == (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits); 722 if ((isUsageBits && size < 4) || 723 (!isUsageBits && code != SET_INTERNAL_OPTION && size < 8)) { 724 // we expect the structure to contain at least the size and 725 // version, 8 bytes total 726 ALOGE("b/27207275 (%zu) (%d/%d)", size, int(index), int(code)); 727 android_errorWriteLog(0x534e4554, "27207275"); 728 } else { 729 err = NO_MEMORY; 730 pageSize = (size_t) sysconf(_SC_PAGE_SIZE); 731 if (size > SIZE_MAX - (pageSize * 2)) { 732 ALOGE("requested param size too big"); 733 } else { 734 allocSize = (size + pageSize * 2) & ~(pageSize - 1); 735 params = mmap(NULL, allocSize, PROT_READ | PROT_WRITE, 736 MAP_PRIVATE | MAP_ANONYMOUS, -1 /* fd */, 0 /* offset */); 737 } 738 if (params != MAP_FAILED) { 739 err = data.read(params, size); 740 if (err != OK) { 741 android_errorWriteLog(0x534e4554, "26914474"); 742 } else { 743 err = NOT_ENOUGH_DATA; 744 OMX_U32 declaredSize = *(OMX_U32*)params; 745 if (code != SET_INTERNAL_OPTION && 746 index != (OMX_INDEXTYPE) OMX_IndexParamConsumerUsageBits && 747 declaredSize > size) { 748 // the buffer says it's bigger than it actually is 749 ALOGE("b/27207275 (%u/%zu)", declaredSize, size); 750 android_errorWriteLog(0x534e4554, "27207275"); 751 } else { 752 // mark the last page as inaccessible, to avoid exploitation 753 // of codecs that access past the end of the allocation because 754 // they didn't check the size 755 mprotect((char*)params + allocSize - pageSize, pageSize, PROT_NONE); 756 switch (code) { 757 case GET_PARAMETER: 758 err = getParameter(node, index, params, size); 759 break; 760 case SET_PARAMETER: 761 err = setParameter(node, index, params, size); 762 break; 763 case GET_CONFIG: 764 err = getConfig(node, index, params, size); 765 break; 766 case SET_CONFIG: 767 err = setConfig(node, index, params, size); 768 break; 769 case SET_INTERNAL_OPTION: 770 { 771 InternalOptionType type = 772 (InternalOptionType)data.readInt32(); 773 774 err = setInternalOption(node, index, type, params, size); 775 break; 776 } 777 778 default: 779 TRESPASS(); 780 } 781 } 782 } 783 } else { 784 ALOGE("couldn't map: %s", strerror(errno)); 785 } 786 } 787 788 reply->writeInt32(err); 789 790 if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) { 791 reply->write(params, size); 792 } 793 794 if (params) { 795 munmap(params, allocSize); 796 } 797 params = NULL; 798 799 return NO_ERROR; 800 } 801 802 case GET_STATE: 803 { 804 CHECK_OMX_INTERFACE(IOMX, data, reply); 805 806 node_id node = (node_id)data.readInt32(); 807 OMX_STATETYPE state = OMX_StateInvalid; 808 809 status_t err = getState(node, &state); 810 reply->writeInt32(state); 811 reply->writeInt32(err); 812 813 return NO_ERROR; 814 } 815 816 case ENABLE_NATIVE_BUFFERS: 817 { 818 CHECK_OMX_INTERFACE(IOMX, data, reply); 819 820 node_id node = (node_id)data.readInt32(); 821 OMX_U32 port_index = data.readInt32(); 822 OMX_BOOL graphic = (OMX_BOOL)data.readInt32(); 823 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 824 825 status_t err = enableNativeBuffers(node, port_index, graphic, enable); 826 reply->writeInt32(err); 827 828 return NO_ERROR; 829 } 830 831 case GET_GRAPHIC_BUFFER_USAGE: 832 { 833 CHECK_OMX_INTERFACE(IOMX, data, reply); 834 835 node_id node = (node_id)data.readInt32(); 836 OMX_U32 port_index = data.readInt32(); 837 838 OMX_U32 usage = 0; 839 status_t err = getGraphicBufferUsage(node, port_index, &usage); 840 reply->writeInt32(err); 841 reply->writeInt32(usage); 842 843 return NO_ERROR; 844 } 845 846 case USE_BUFFER: 847 { 848 CHECK_OMX_INTERFACE(IOMX, data, reply); 849 850 node_id node = (node_id)data.readInt32(); 851 OMX_U32 port_index = data.readInt32(); 852 sp<IMemory> params = 853 interface_cast<IMemory>(data.readStrongBinder()); 854 OMX_U32 allottedSize = data.readInt32(); 855 856 if (params == NULL) { 857 ALOGE("b/26392700"); 858 reply->writeInt32(INVALID_OPERATION); 859 return NO_ERROR; 860 } 861 862 buffer_id buffer; 863 status_t err = useBuffer(node, port_index, params, &buffer, allottedSize); 864 reply->writeInt32(err); 865 866 if (err == OK) { 867 reply->writeInt32((int32_t)buffer); 868 } 869 870 return NO_ERROR; 871 } 872 873 case USE_GRAPHIC_BUFFER: 874 { 875 CHECK_OMX_INTERFACE(IOMX, data, reply); 876 877 node_id node = (node_id)data.readInt32(); 878 OMX_U32 port_index = data.readInt32(); 879 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 880 data.read(*graphicBuffer); 881 882 buffer_id buffer; 883 status_t err = useGraphicBuffer( 884 node, port_index, graphicBuffer, &buffer); 885 reply->writeInt32(err); 886 887 if (err == OK) { 888 reply->writeInt32((int32_t)buffer); 889 } 890 891 return NO_ERROR; 892 } 893 894 case UPDATE_GRAPHIC_BUFFER_IN_META: 895 { 896 CHECK_OMX_INTERFACE(IOMX, data, reply); 897 898 node_id node = (node_id)data.readInt32(); 899 OMX_U32 port_index = data.readInt32(); 900 sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); 901 data.read(*graphicBuffer); 902 buffer_id buffer = (buffer_id)data.readInt32(); 903 904 status_t err = updateGraphicBufferInMeta( 905 node, port_index, graphicBuffer, buffer); 906 reply->writeInt32(err); 907 908 return NO_ERROR; 909 } 910 911 case CREATE_INPUT_SURFACE: 912 { 913 CHECK_OMX_INTERFACE(IOMX, data, reply); 914 915 node_id node = (node_id)data.readInt32(); 916 OMX_U32 port_index = data.readInt32(); 917 android_dataspace dataSpace = (android_dataspace)data.readInt32(); 918 919 sp<IGraphicBufferProducer> bufferProducer; 920 MetadataBufferType type = kMetadataBufferTypeInvalid; 921 status_t err = createInputSurface(node, port_index, dataSpace, &bufferProducer, &type); 922 923 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 924 android_errorWriteLog(0x534e4554, "26324358"); 925 } 926 927 reply->writeInt32(type); 928 reply->writeInt32(err); 929 930 if (err == OK) { 931 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 932 } 933 934 return NO_ERROR; 935 } 936 937 case CREATE_PERSISTENT_INPUT_SURFACE: 938 { 939 CHECK_OMX_INTERFACE(IOMX, data, reply); 940 941 sp<IGraphicBufferProducer> bufferProducer; 942 sp<IGraphicBufferConsumer> bufferConsumer; 943 status_t err = createPersistentInputSurface( 944 &bufferProducer, &bufferConsumer); 945 946 reply->writeInt32(err); 947 948 if (err == OK) { 949 reply->writeStrongBinder(IInterface::asBinder(bufferProducer)); 950 reply->writeStrongBinder(IInterface::asBinder(bufferConsumer)); 951 } 952 953 return NO_ERROR; 954 } 955 956 case SET_INPUT_SURFACE: 957 { 958 CHECK_OMX_INTERFACE(IOMX, data, reply); 959 960 node_id node = (node_id)data.readInt32(); 961 OMX_U32 port_index = data.readInt32(); 962 963 sp<IGraphicBufferConsumer> bufferConsumer = 964 interface_cast<IGraphicBufferConsumer>(data.readStrongBinder()); 965 966 MetadataBufferType type = kMetadataBufferTypeInvalid; 967 968 status_t err = INVALID_OPERATION; 969 if (bufferConsumer == NULL) { 970 ALOGE("b/26392700"); 971 } else { 972 err = setInputSurface(node, port_index, bufferConsumer, &type); 973 974 if ((err != OK) && (type == kMetadataBufferTypeInvalid)) { 975 android_errorWriteLog(0x534e4554, "26324358"); 976 } 977 } 978 979 reply->writeInt32(type); 980 reply->writeInt32(err); 981 return NO_ERROR; 982 } 983 984 case SIGNAL_END_OF_INPUT_STREAM: 985 { 986 CHECK_OMX_INTERFACE(IOMX, data, reply); 987 988 node_id node = (node_id)data.readInt32(); 989 990 status_t err = signalEndOfInputStream(node); 991 reply->writeInt32(err); 992 993 return NO_ERROR; 994 } 995 996 case STORE_META_DATA_IN_BUFFERS: 997 { 998 CHECK_OMX_INTERFACE(IOMX, data, reply); 999 1000 node_id node = (node_id)data.readInt32(); 1001 OMX_U32 port_index = data.readInt32(); 1002 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 1003 1004 MetadataBufferType type = kMetadataBufferTypeInvalid; 1005 status_t err = storeMetaDataInBuffers(node, port_index, enable, &type); 1006 1007 reply->writeInt32(type); 1008 reply->writeInt32(err); 1009 1010 return NO_ERROR; 1011 } 1012 1013 case PREPARE_FOR_ADAPTIVE_PLAYBACK: 1014 { 1015 CHECK_OMX_INTERFACE(IOMX, data, reply); 1016 1017 node_id node = (node_id)data.readInt32(); 1018 OMX_U32 port_index = data.readInt32(); 1019 OMX_BOOL enable = (OMX_BOOL)data.readInt32(); 1020 OMX_U32 max_width = data.readInt32(); 1021 OMX_U32 max_height = data.readInt32(); 1022 1023 status_t err = prepareForAdaptivePlayback( 1024 node, port_index, enable, max_width, max_height); 1025 reply->writeInt32(err); 1026 1027 return NO_ERROR; 1028 } 1029 1030 case CONFIGURE_VIDEO_TUNNEL_MODE: 1031 { 1032 CHECK_OMX_INTERFACE(IOMX, data, reply); 1033 1034 node_id node = (node_id)data.readInt32(); 1035 OMX_U32 port_index = data.readInt32(); 1036 OMX_BOOL tunneled = (OMX_BOOL)data.readInt32(); 1037 OMX_U32 audio_hw_sync = data.readInt32(); 1038 1039 native_handle_t *sideband_handle = NULL; 1040 status_t err = configureVideoTunnelMode( 1041 node, port_index, tunneled, audio_hw_sync, &sideband_handle); 1042 reply->writeInt32(err); 1043 if(err == OK){ 1044 reply->writeNativeHandle(sideband_handle); 1045 } 1046 1047 return NO_ERROR; 1048 } 1049 1050 case ALLOC_SECURE_BUFFER: 1051 { 1052 CHECK_OMX_INTERFACE(IOMX, data, reply); 1053 1054 node_id node = (node_id)data.readInt32(); 1055 OMX_U32 port_index = data.readInt32(); 1056 if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) { 1057 ALOGE("b/24310423"); 1058 reply->writeInt32(INVALID_OPERATION); 1059 return NO_ERROR; 1060 } 1061 1062 size_t size = data.readInt64(); 1063 1064 buffer_id buffer; 1065 void *buffer_data = NULL; 1066 native_handle_t *native_handle = NULL; 1067 status_t err = allocateSecureBuffer( 1068 node, port_index, size, &buffer, &buffer_data, &native_handle); 1069 reply->writeInt32(err); 1070 1071 if (err == OK) { 1072 reply->writeInt32((int32_t)buffer); 1073 reply->writeInt64((uintptr_t)buffer_data); 1074 if (buffer_data == NULL) { 1075 reply->writeNativeHandle(native_handle); 1076 } 1077 } 1078 1079 return NO_ERROR; 1080 } 1081 1082 case ALLOC_BUFFER_WITH_BACKUP: 1083 { 1084 CHECK_OMX_INTERFACE(IOMX, data, reply); 1085 1086 node_id node = (node_id)data.readInt32(); 1087 OMX_U32 port_index = data.readInt32(); 1088 sp<IMemory> params = 1089 interface_cast<IMemory>(data.readStrongBinder()); 1090 OMX_U32 allottedSize = data.readInt32(); 1091 1092 if (params == NULL) { 1093 ALOGE("b/26392700"); 1094 reply->writeInt32(INVALID_OPERATION); 1095 return NO_ERROR; 1096 } 1097 1098 buffer_id buffer; 1099 status_t err = allocateBufferWithBackup( 1100 node, port_index, params, &buffer, allottedSize); 1101 1102 reply->writeInt32(err); 1103 1104 if (err == OK) { 1105 reply->writeInt32((int32_t)buffer); 1106 } 1107 1108 return NO_ERROR; 1109 } 1110 1111 case FREE_BUFFER: 1112 { 1113 CHECK_OMX_INTERFACE(IOMX, data, reply); 1114 1115 node_id node = (node_id)data.readInt32(); 1116 OMX_U32 port_index = data.readInt32(); 1117 buffer_id buffer = (buffer_id)data.readInt32(); 1118 reply->writeInt32(freeBuffer(node, port_index, buffer)); 1119 1120 return NO_ERROR; 1121 } 1122 1123 case FILL_BUFFER: 1124 { 1125 CHECK_OMX_INTERFACE(IOMX, data, reply); 1126 1127 node_id node = (node_id)data.readInt32(); 1128 buffer_id buffer = (buffer_id)data.readInt32(); 1129 bool haveFence = data.readInt32(); 1130 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1131 reply->writeInt32(fillBuffer(node, buffer, fenceFd)); 1132 1133 return NO_ERROR; 1134 } 1135 1136 case EMPTY_BUFFER: 1137 { 1138 CHECK_OMX_INTERFACE(IOMX, data, reply); 1139 1140 node_id node = (node_id)data.readInt32(); 1141 buffer_id buffer = (buffer_id)data.readInt32(); 1142 OMX_U32 range_offset = data.readInt32(); 1143 OMX_U32 range_length = data.readInt32(); 1144 OMX_U32 flags = data.readInt32(); 1145 OMX_TICKS timestamp = data.readInt64(); 1146 bool haveFence = data.readInt32(); 1147 int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1148 reply->writeInt32(emptyBuffer( 1149 node, buffer, range_offset, range_length, flags, timestamp, fenceFd)); 1150 1151 return NO_ERROR; 1152 } 1153 1154 case GET_EXTENSION_INDEX: 1155 { 1156 CHECK_OMX_INTERFACE(IOMX, data, reply); 1157 1158 node_id node = (node_id)data.readInt32(); 1159 const char *parameter_name = data.readCString(); 1160 1161 if (parameter_name == NULL) { 1162 ALOGE("b/26392700"); 1163 reply->writeInt32(INVALID_OPERATION); 1164 return NO_ERROR; 1165 } 1166 1167 OMX_INDEXTYPE index; 1168 status_t err = getExtensionIndex(node, parameter_name, &index); 1169 1170 reply->writeInt32(err); 1171 1172 if (err == OK) { 1173 reply->writeInt32(index); 1174 } 1175 1176 return OK; 1177 } 1178 1179 default: 1180 return BBinder::onTransact(code, data, reply, flags); 1181 } 1182} 1183 1184//////////////////////////////////////////////////////////////////////////////// 1185 1186class BpOMXObserver : public BpInterface<IOMXObserver> { 1187public: 1188 BpOMXObserver(const sp<IBinder> &impl) 1189 : BpInterface<IOMXObserver>(impl) { 1190 } 1191 1192 virtual void onMessages(const std::list<omx_message> &messages) { 1193 Parcel data, reply; 1194 std::list<omx_message>::const_iterator it = messages.cbegin(); 1195 bool first = true; 1196 while (it != messages.cend()) { 1197 const omx_message &msg = *it++; 1198 if (first) { 1199 data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor()); 1200 data.writeInt32(msg.node); 1201 first = false; 1202 } 1203 data.writeInt32(msg.fenceFd >= 0); 1204 if (msg.fenceFd >= 0) { 1205 data.writeFileDescriptor(msg.fenceFd, true /* takeOwnership */); 1206 } 1207 data.writeInt32(msg.type); 1208 data.write(&msg.u, sizeof(msg.u)); 1209 ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg)); 1210 } 1211 if (!first) { 1212 data.writeInt32(-1); // mark end 1213 remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY); 1214 } 1215 } 1216}; 1217 1218IMPLEMENT_META_INTERFACE(OMXObserver, "android.hardware.IOMXObserver"); 1219 1220status_t BnOMXObserver::onTransact( 1221 uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 1222 switch (code) { 1223 case OBSERVER_ON_MSG: 1224 { 1225 CHECK_OMX_INTERFACE(IOMXObserver, data, reply); 1226 IOMX::node_id node = data.readInt32(); 1227 std::list<omx_message> messages; 1228 status_t err = FAILED_TRANSACTION; // must receive at least one message 1229 do { 1230 int haveFence = data.readInt32(); 1231 if (haveFence < 0) { // we use -1 to mark end of messages 1232 break; 1233 } 1234 omx_message msg; 1235 msg.node = node; 1236 msg.fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1; 1237 msg.type = (typeof(msg.type))data.readInt32(); 1238 err = data.read(&msg.u, sizeof(msg.u)); 1239 ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg)); 1240 messages.push_back(msg); 1241 } while (err == OK); 1242 1243 if (err == OK) { 1244 onMessages(messages); 1245 } 1246 1247 return err; 1248 } 1249 1250 default: 1251 return BBinder::onTransact(code, data, reply, flags); 1252 } 1253} 1254 1255} // namespace android 1256