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