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