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